From 2b4adc5124f0fdbf200e81c9890e006fb502e64c Mon Sep 17 00:00:00 2001 From: testadmin Date: Tue, 28 Apr 2026 22:32:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20USDT=E2=86=92USDC=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E6=9B=BF=E6=8D=A2=20+=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E5=B8=81=E7=A7=8D=E6=94=B9=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/AccountLog.php | 1009 +++++++++++++++++++ app/Currency.php | 129 +++ app/Http/mode/Sina.php | 1332 ++++++++++++++++++++++++++ app/Users.php | 452 +++++++++ app/UsersWallet.php | 235 +++++ app/Utils/Workerman/WsConnection.php | 1313 +++++++++++++++++++++++++ 6 files changed, 4470 insertions(+) create mode 100644 app/AccountLog.php create mode 100644 app/Currency.php create mode 100644 app/Http/mode/Sina.php create mode 100644 app/Users.php create mode 100644 app/UsersWallet.php create mode 100644 app/Utils/Workerman/WsConnection.php diff --git a/app/AccountLog.php b/app/AccountLog.php new file mode 100644 index 0000000..43248e5 --- /dev/null +++ b/app/AccountLog.php @@ -0,0 +1,1009 @@ +hasOne('App\Users', 'id', 'user_id')->value('account_number'); + } + + public function getFromUserIdAttribute() + { + //return $this->hasOne('App\WalletLog', 'account_log_id', 'id')->value('from_user_id'); + return $this->walletLog()->value('from_user_id'); + } + + public function user1() + { + return $this->belongsTo('App\Users', 'user_id', 'id'); + } + + public function getAccountAttribute() + { + $value = $this->hasOne('App\Users', 'id', 'user_id')->value('phone'); + if (empty($value)) { + $value = $this->hasOne('App\Users', 'id', 'user_id')->value('email'); + } + return $value; + } + + public function getCreatedTimeAttribute() + { + $value = $this->attributes['created_time']; + return $value ? date('Y-m-d H:i:s', $value) : ''; + } + + public function getBeforeAttribute() + { + return $this->walletLog()->value('before'); + } + public function getAfterAttribute() + { + return $this->walletLog()->value('after'); + } + + public function getTransactionInfoAttribute() + { + $type1 = [ + '0' => '无', + '1' => '资金', + '2' => '币币', + '3' => '合约', + '4' => '期权', + '5'=>'保险' + ]; + $type2 = ['', '[锁定]']; + $balance_type = $this->walletLog()->value('balance_type'); + $lock_tpye = $this->walletLog()->value('lock_type'); + array_key_exists($balance_type, $type1) ? : $balance_type = 0; + array_key_exists($lock_tpye, $type2) ? : $lock_tpye = 0; + return $type1[$balance_type] . $type2[$lock_tpye]; + + } + + public function getCurrencyNameAttribute() + { + return $this->hasOne('App\Currency', 'id', 'currency')->value('name'); + } + + public static function insertLog($data = array(), $data2 = array()) + { + $data = is_array($data) ? $data : func_get_args(); + $log = new self(); + $log->user_id = $data['user_id'] ?? false;; + $log->value = $data['value'] ?? ''; + $log->created_time = $data['created_time'] ?? time(); + $log->info = $data['info'] ?? ''; + $log->type = $data['type'] ?? 0; + $log->currency = $data['currency'] ?? 0; + $data_wallet['balance_type'] = $data2['balance_type'] ?? 0; + $data_wallet['wallet_id'] = $data2['wallet_id'] ?? 0; + $data_wallet['lock_type'] = $data2['lock_type'] ?? 0; + $data_wallet['before'] = $data2['before'] ?? 0; + $data_wallet['change'] = $data2['change'] ?? 0; + $data_wallet['after'] = $data2['after'] ?? 0; + $data_wallet['memo'] = $data['info'] ?? 0; + $data_wallet['create_time'] = $data2['create_time'] ?? time(); + //dd($data_wallet); + try { + DB::transaction(function () use ($log, $data_wallet) { + $log->save(); + $log->walletLog()->create($data_wallet); + }); + return true; + } catch (\Exception $ex) { + throw new \Exception($ex->getMessage()); + return false; + } + } + + public static function newinsertLog($data = array(), $data2 = array()) + { + $data = is_array($data) ? $data : func_get_args(); + $log = new self(); + $log->user_id = $data['user_id'] ?? false;; + $log->value = $data['value'] ?? ''; + $log->created_time = $data['created_time'] ?? time(); + $log->info = $data['info'] ?? ''; + $log->type = $data['type'] ?? 0; + $log->currency = $data['currency'] ?? 0; +// $data_wallet['balance_type'] = $data2['balance_type']?? 0; +// $data_wallet['wallet_id'] = $data2['wallet_id']?? 0; +// $data_wallet['lock_type'] = $data2['lock_type']?? 0; +// $data_wallet['before'] = $data2['before']?? 0; +// $data_wallet['change'] = $data2['change']?? 0; +// $data_wallet['after'] = $data2['after']?? 0; +// $data_wallet['memo'] = $data['info']?? 0; +// $data_wallet['create_time'] = $data2['create_time']?? time(); + //dd($data_wallet); + try { + DB::transaction(function () use ($log) { + $log->save(); +// $log->walletLog()->create($data_wallet); + }); + return true; + } catch (\Exception $ex) { + throw new \Exception($ex->getMessage()); + return false; + } + } + + + public function getInfoAttribute() + { + $type = $this->attributes['type']; + if ($type == 8) { + $type = 3; + } + if ($type == 502) { + $type = 8; + } + // var_dump($this); + $prefix = ''; + //$lang = session()->get('lang'); + if ($this->attributes['is_lock']) { + $prefix = str_replace('account_log_info.', '', __("account_log_info.is_lock")) . ' '; + } + $info = str_replace('account_log_info.', '', __("account_log_info.$type")); + if ($info == $type) { + $info = str_replace('account_log_info.', '', __("account_log_info.unknown")); + } + + return $prefix . $info; + } + + + public static function getTypeInfo($type) + { + switch ($type) { + + case self::ADMIN_LEGAL_BALANCE: + return '后台调节资金账户余额'; + break; + case self::ADMIN_LOCK_LEGAL_BALANCE: + return '后台调节资金账户锁定余额'; + break; + case self::ADMIN_CHANGE_BALANCE: + return '后台调节币币账户余额'; + break; + case self::ADMIN_LOCK_CHANGE_BALANCE: + return '后台调节币币账户锁定余额'; + break; + case self::ADMIN_LEVER_BALANCE: + return '后台调节合约账户余额'; + break; + case self::ADMIN_LOCK_LEVER_BALANCE: + return '后台调节合约账户锁定余额'; + break; + case self::ADMIN_MICRO_BALANCE: + return '后台调节期权账户余额'; + break; + case self::ADMIN_LOCK_MICRO_BALANCE: + return '后台调节期权账户锁定余额'; + break; + case self::WALLET_LEGAL_OUT: + return '资金账户转出至交易账户'; + break; + case self::WALLET_LEGAL_IN: + return '交易账户转入至资金账户'; + break; + case self::WALLET_CHANGE_OUT: + return '交易账户转出至资金账户'; + break; + case self::WALLET_CHANGE_IN: + return '资金账户转入交易账户'; + break; + case self::WALLET_CHANGE_LEVEL_IN: + return '合约账户转入交易账户'; + break; + case self::WALLET_CHANGE_LEVEL_OUT: + return '交易账户转出至合约账户'; + break; + case self::WALLET_LEVEL_OUT: + return '合约账户转出至交易账户'; + break; + case self::WALLET_LEVEL_IN: + return '交易账户转入合约账户'; + break; + case self::INVITATION_TO_RETURN: + return '邀请返佣金'; + break; + case self::WALLETOUT: + return '用户提币'; + break; + case self::TRANSACTIONIN_IN_DEL: + return '取消买入交易'; + break; + case self::TRANSACTIONIN_OUT_DEL: + return '取消卖出交易'; + break; + case self::INTO_TRA_FB: + return '美丽链资金交易余额转入'; + break; + case self::INTO_TRA_BB: + return '美丽链币币交易余额转入'; + break; + case self::INTO_TRA_GG: + return '美丽链合约交易余额转入'; + break; + case self::WALLET_LEGAL_LEVEL_OUT: + return '资金转入合约,资金减少'; + break; + case self::WALLET_LEGAL_LEVEL_IN: + return '资金转入合约,合约增加'; + break; + case self::WALLET_LEVEL_LEGAL_OUT: + return '合约转资金审核通过,合约减少'; + break; + case self::WALLET_LEVEL_LEGAL_IN: + return '合约转资金审核通过,资金增加'; + break; + case self::WALLET_MICRO_LEVEL_OUT: + return '期权转入合约,期权减少'; + break; + case self::WALLET_MICRO_LEVEL_IN : + return '期权转入合约,合约增加'; + break; + case self::WALLET_LEVEL_MICRO_OUT : + return '合约转期权审核通过,合约减少'; + break; + case self::WALLET_LEVEL_MICRO_IN: + return '合约转期权审核通过,期权增加'; + break; + case self::WALLET_LEGAL_MICRO_OUT: + return '资金转入期权,资金减少'; + break; + case self::WALLET_LEGAL_MICRO_IN : + return '资金转入期权,期权增加'; + break; + case self::WALLET_MICRO_LEGAL_OUT : + return '期权转资金审核通过,期权减少'; + break; + case self::WALLET_MICRO_LEGAL_IN : + return '期权转资金审核通过,资金增加'; + break; + + case self::WALLET_DONGJIEGANGGAN: + return '合约转资金,冻结合约转化值'; + break; + case self::WALLET_JIEDONGGANGGAN: + return '合约转资金,审核不通过解冻'; + break; + case self::CANDY_TOUSDT_CANDY: + return '通证兑换USDC'; + break; + case self::CANDY_LEVER_BALANCE: + return '通证兑换,合约币增加'; + break; + case self::PROFIT_LOSS_RELEASE: + return '历史盈亏释放,增加合约币'; + break; + case self::REWARD_CANDY: + return '奖励通证'; + break; + case self::REWARD_CURRENCY: + return '奖励数字货币'; + break; + case self::ADMIN_CANDY_BALANCE: + return '后台调节通证'; + break; + case self::TOBE_SELLER_SUB_USDT: + return '申请成为商家扣除USDC'; + break; + case self::CURRENCY_TO_USDT_MUL: + return '资产兑换,减少持有币资金'; + break; + case self::CURRENCY_TO_USDT_ADD: + return '资产兑换,增加USDC资金'; + break; + case self::JOIN_BOSS: + return '激活BOSS'; + case self::TRANSFER_TO_LH_ACCOUNT: + return '转账至余币宝钱包'; + case self::BOSS_WITHDRAW: + return '从BOSS账户中转出余额'; + case self::BANK_WITHDRAW: + return '余币宝提现'; + case self::LH_LOAN: + return '质押'; + default: + return '暂无此类型'; + break; + } + } + + /*public static function getTypeInfo($type) + { + switch ($type) { + case self::BUY_BLOCK_CHAIN: + return '购买区块链'; + break; + case self::ADJUDT_SUB_BALANCE: + return '后台调节账户余额'; + break; + case self::ADMIN_LOCK_BALANCE: + return '后台调节锁定余额'; + break; + case self::ADMIN_REMAIN_LOCK_BALANCE: + return '后台调节锁定余额变动剩余锁定余额'; + break; + case self::ACCEPTOR_SELL: + return '用户提现承兑申请'; + break; + case self::ACCEPTOR_RECHARGE: + return '用户充值承兑确认'; + break; + case self::ACCEPTOR_RECHARGE_VAR: + return '用户充值承兑手续费'; + break; + case self::ACCEPTOR_RECHARGE_DEC: + return '确认用户充值,承兑商充值额度减少'; + break; + case self::ACCEPTOR_CASH_INC: + return '确认用户充值,承兑商提现额度增加'; + break; + case self::ACCEPTOR_CASH_DEC: + return '确认用户提现,承兑商提现额度减少'; + break; + case self::ACCEPTOR_RECHARGE_INC: + return '确认用户提现,承兑商充值额度增加'; + break; + case self::ACCEPTOR_SELL_RETURN: + return '取消用户提现承兑申请'; + break; + default: + return '暂无此类型'; + break; + } + }*/ + + public function getTypeInfoMAttribute(){ + $value = $this->attributes['type']; + $a = [ + 1=>"後台調節資金賬戶餘額", + 2=>"后台调节资金账户锁定余额", + 3=>"後台調節幣幣賬戶餘額", + 4=>"後台調節幣幣賬戶鎖定餘額", + 5=>"後台調節合約賬戶餘額", + 6=>"後台調節合約賬戶鎖定餘額", +// 7=>"後台調節期權賬戶餘額", +// 8=>"後台調節期權賬戶鎖定餘額", + 7=>"提幣記錄", + 8=>"充幣記錄", + 11=>"資金劃入記錄", + 12=>"資金劃出記錄", + 13=>"資金劃出記錄", + 14=>"資金劃出記錄", + 60=>"商家發布資金出售", + 61=>"出售給商家資金", + 62=>"用戶購買商家資金成功", + 63=>"商家購買用戶資金成功", + 64=>"出售給商家資金-取消", + 70=>"後台調節商家餘額", + 71=>"商家撤回發布資金出售", + 72=>"商家撤回發布資金出售", + /* + 2=>"後台調節賬戶餘額", + 3=>"轉入", + 4=>"轉出", + 9=>"後台調節鎖定餘額", + 10=>"後台調節鎖定餘額相應剩餘鎖定餘額", + 11=>"鎖倉增加", + 13=>"用户提现承兑申请", + 14=>"用戶充值承兌確認", + 15=>"用戶充值承兌手續費", + 16=>"確認用戶充值,承兌商充值額度減少", + 17=>"確認用戶充值,承兌商提現額度增加", + 18=>"確認用戶提現,承兌商提現額度減少", + 19=>"確認用戶提現,承兌商充值額度增加", + 20=>"取消用戶提現承兌申請", + 91=>"取消用戶提現承兌,承兌商提現額度增加", + */ + + 15=>"幣幣劃轉合約", + 16=>"合約劃轉幣幣", + 21=>"提交賣出,扣除", + 22=>"買入扣除", + 23=>"扣除賣方", + 24=>"提交買入,扣除", + 25=>"買方增加幣", + 26=>"賣方增加cny", + 27=>"撤銷增加", + 28=>"撤銷增加", + 29=>"賣出手續費", + 30=>"合約交易扣除保證金", + 31=>"平倉增加", + 32=>"爆倉凍結", + 34=>"隔夜費", + 35=>"交易手續費", + 36=>"合約交易取消", + 37=>"通證兌換合約幣增加", + 38=>"申請成為商家扣除USDC", + 39=>"資產兌換 減少兌換幣", + 40=>"資產兌換 增加USDC資金", + 50 => '幣幣交易凍結', + 51 => '幣幣交易', + 99=>"用戶申請提幣", + 100=>"用戶提幣成功", + 101=>"用戶提幣失敗", + 102=>"取消買入交易", + 103=>"取消買出交易", + 104=>"合約交易賬戶變化", + 105=>"獎勵通證", + 106=>"獎勵數字貨幣", + 107=>"通證兌換USDC", + 108=>"後臺調節通證", + 299=>"合約交易賬戶變化", + 401=>"轉賬", + 200=>"充幣增加余額", + //c2c交易 + 201=>"用戶發布資金出售", + 202=>"自動取消c2c資金交易", + 203=>"出售給用戶資金", + 204=>"用戶購買資金成功", + 205=>"商家撤回發布資金出售", + 206=>"資金(c2c)轉入合約", + 207=>"資金(c2c)轉入合約", + 208=>"合約轉入資金(c2c)", + 209=>"合約轉入資金(c2c)", + 211=>"審核不通過解凍合約凍結", + 212=>"歷史盈虧釋放,增加合約幣", + 501=>"期權下單", + 502=>"期權平倉結算", + 600=>"閃兌減少余額", + 601=>"閃兌通過,增加余額", + 602=>"閃兌減少鎖定余額", + 603=>"閃兌增加鎖定余額", + 604=>"閃兌駁回,增加余額", +// +// 206=>"期權(c2c)轉入合約", +// 207=>"期權(c2c)轉入合約", +// 208=>"合約轉入期權(c2c)", +// 209=>"合約轉入期權(c2c)", +// 206=>"資金(c2c)轉入期權", +// 207=>"資金(c2c)轉入期權", +// 208=>"期權轉入資金(c2c)", +// 209=>"期權轉入資金(c2c)", +// 206=>"閃兌轉入合約", +// 207=>"閃兌轉入合約", +// 208=>"合約轉入閃兌", +// 209=>"合約轉入閃兌", + + 220=>"USDC兑换bmb 减少USDC", + 221=>"USDC兌換手續費", + 230=>"用戶購買保險", + 231=>"賠償用戶", + 232=>"賠償用戶,清除受保金額", + 233=>"保險解約,清除受保金額", + 234=>"保險解約,清除保險金額", +// 234=>"保險解約,賠付用戶", + 235=>"釋放保險交易手續費", + 250=>"下級返利", + 251=>"持幣生幣", + 1001=>"合約劃轉合約", + 1002=>"合約劃轉合約", + 1003=>"秒合約下單扣除本金", + 1004=>"鎖倉", + 2022=>"申購新幣", + 2023=>"申購新幣收益", + + ]; + return $a[$value]??'未知類型'; + } + + public function getTypeInfoEAttribute(){ + $value = $this->attributes['type']; + $a = [ + 1=>"Backstage adjustment of fund account balance", + 2=>"Adjust the locked balance of the fund account in the background", + 3=>"Backstage adjustment of currency account balance", + 4=>"Adjust the locked balance of the currency account in the background", + 5=>"Backstage adjustment of contract account balance", + 6=>"Adjust the locked balance of contract account in the background", + 7=>"Backstage adjustment of option account balance", + 8=>"Adjust the locked balance of option account in the background", +// 7=>"Withdrawal record", +// 8=>"Deposit record", + 11=>"Fund transfer record", + 12=>"Fund transfer record", + 13=>"Fund transfer record", + 14=>"Fund transfer record", + 60=>"Merchant releases funds for sale", + 61=>"Sell to merchant funds", + 62=>"User purchases merchant funds successfully", + 63=>"Merchant purchases user funds successfully", + 64=>"Sell to Merchant Funds-Cancel", + 70=>"Backstage adjustment of merchant balance", + 71=>"Merchants withdraw the release funds for sale", + 72=>"Merchants withdraw the release funds for sale", + /* + 2=>"Backstage adjustment of account balance", + 3=>"Transfer in", + 4=>"Transfer out", + 9=>"Background adjustment lock balance", + 10=>"Background adjustment of locked balance corresponding to remaining locked balance", + 11=>"Increase in lock-up", + 13=>"User withdrawal and acceptance application", + 14=>"User deposit acceptance confirmation", + 15=>"User recharge acceptance fee", + 16=>"Confirm the user's recharge, the acceptor's recharge limit is reduced", + 17=>"Confirm user recharge, the acceptor's withdrawal limit increases", + 18=>"Confirm that the user withdraws, and the amount of withdrawal by the acceptor decreases", + 19=>"Confirm that the user withdraws cash, and the acceptor's recharge amount increases", + 20=>"Cancel user withdrawal acceptance application", + 91=>"Cancellation of user withdrawal acceptance and increase of withdrawal amount of acceptor", + */ + + 15=>"Coin To Contract", + 16=>"Contract To exchange", + 21=>"Submit sell, deduct", + 22=>"Purchase deduction", + 23=>"Deduction of seller", + 24=>"Submit buy, deduct", + 25=>"Buyer increases currency", + 26=>"CNY added by seller", + 27=>"Withdrawal of addition", + 28=>"Withdrawal of addition", + 29=>"Service charge for selling", + 30=>"Contract transaction deducting margin", + 31=>"Closing increased", + 32=>"Frozen warehouse", + 34=>"Overnight fee", + 35=>"Transaction fee", + 36=>"Cancellation of contract transaction", + 37=>"Currency increase in exchange of token", + 38=>"Apply to become a merchant and deduct USDC", + 39=>"Decrease in exchange currency", + 40=>"Asset exchange increases USDC funds", + 50=>'Currency transaction frozen', + 51=>'Currency transaction', + 99=>"User application for withdrawal of currency", + 100=>"User withdraws currency successfully", + 101=>"User failed to withdraw currency", + 102=>"Cancel buy", + 103=>"Cancel buy out", + 104=>"Contract trading account changes", + 105=>"Reward pass", + 106=>"Reward digital currency", + 107=>"Exchange of token for USDC", + 108=>"Background regulation pass", + 299=>"Contract trading account changes", + 401=>"Transfer", + 200=>"Increase balance by replenishing currency", + //c2c交易 + 201=>"Users release funds for sale", + 202=>"Automatic cancellation of C2C fund transaction", + 203=>"Funds sold to users", + 204=>"Successful purchase of funds by user", + 205=>"Merchant withdraws release fund sale", + 206=>"Fund (C2C) transfer contract", + 207=>"Fund (C2C) transfer contract", + 208=>"Contract transfer in funds (C2C)", + 209=>"Contract transfer in funds (C2C)", + 211=>"Unfreeze contract freeze if audit fails", + 212=>"Release of historical profit and loss, increase contract currency", + 501=>"Option placing", + 502=>"Option closing settlement", + 600=>"Decrease balance of flash cash", + 601=>"Flash through, increase balance", + 602=>"Flash cash reduces locked balance", + 603=>"Flash cash increases lock up balance", + 604=>"Flash cash rejected, increase balance", +// +// 206=>"Option (C2C) transfer contract", +// 207=>"Option (C2C) transfer contract", +// 208=>"Contract transfer option (C2C)", +// 209=>"Contract transfer option (C2C)", +// 206=>"Capital (C2C) transfer option", +// 207=>"Capital (C2C) transfer option", +// 208=>"Funds transferred from options (C2C)", +// 209=>"Funds transferred from options (C2C)", +// 206=>"Flash transfer contract", +// 207=>"Flash transfer contract", +// 208=>"Contract transfer to flash cash", +// 209=>"Contract transfer to flash cash", + + 220=>"USDC exchange for BMB reduces USDC", + 221=>"USDC exchange fee", + 230=>"User purchase insurance", + 231=>"Compensate users", + 232=>"Compensate the user and clear the insured amount", + 233=>"Cancellation of insurance", + 234=>"Cancellation of insurance", +// 234=>"Insurance termination, compensation for users", + 235=>"Release of insurance transaction fees", + 250=>"Subordinate rebate", + 251=>"Holding currency", + 1001=>"Contract To Contract", + 1002=>"Contract To Contract", + 1003=>"Deduction of purchase contract", + 1004=>"Lock position", + 2022=>"Apply for SGD", + 2023=>"Subscription of new currency income", + ]; + return $a[$value]??'Unknow Operation'; + } + public function getTypeInfoJAttribute(){ + $value = $this->attributes['type']; + $a = [ + 1=>"資金口座残高のバックステージ調整", + 2=>"バックグラウンドでファンド口座のロックされた残高を調整します", + 3=>"通貨口座残高のバックステージ調整", + 4=>"バックグラウンドで通貨口座のロックされた残高を調整する", + 5=>"契約口座残高のバックステージ調整", + 6=>"バックグラウンドで契約アカウントのロックされた残高を調整する", + 7=>"オプション口座残高のバックステージ調整", + 8=>"バックグラウンドでオプション口座の固定残高を調整します", +// 7=>"出金記録", +// 8=>"預金実績", + 11=>"送金実績", + 12=>"送金実績", + 13=>"送金実績", + 14=>"送金実績", + 60=>"商人は販売のための資金を解放します", + 61=>"マーチャントファンドに売ります", + 62=>"ユーザーが販売者の資金を正常に購入した", + 63=>"販売者がユーザーの資金を正常に購入", + 64=>"マーチャントファンドへの販売-キャンセル", + 70=>"販売者の残高の舞台裏での調整", + 71=>"商人は販売のためのリリース資金を引き出します", + 72=>"商人は販売のためのリリース資金を引き出します", + /* + 2=>"口座残高のバックステージ調整", + 3=>"乗り換え", + 4=>"転出する", + 9=>"背景調整ロックバランス", + 10=>"残りのロックされたバランスに対応するロックされたバランスのバックグラウンド調整", + 11=>"ロックアップの増加", + 13=>"ユーザーの脱退および承認申請", + 14=>"ユーザー入金受付確認", + 15=>"ユーザーリチャージ受付手数料", + 16=>"ユーザーの再充電を確認すると、アクセプターの再充電制限が引き下げられます", + 17=>"ユーザーの再充電を確認すると、アクセプターの引き出し限度額が増加します", + 18=>"ユーザーの現金引き出しを確認し、引受人の現金引き出し額が減少した。", + 19=>"ユーザーの現金引き出しを確認し、引受人のチャージ額が増加した。", + 20=>"ユーザーの現金引受申請をキャンセルします。", + 91=>"ユーザーの現金引受をキャンセルし、引受人の現金引受額が増加しました。", + */ + + 15=>"コイン換算契約", + 16=>"契約換算コイン", + 21=>"販売の提出、控除", + 22=>"買取控除", + 23=>"控除売り方", + 24=>"購入の提出、控除", + 25=>"買い手が貨幣を増やす", + 26=>"売り手増加cny", + 27=>"取消し追加", + 28=>"取消し追加", + 29=>"販売手数料", + 30=>"契約取引控除保証金", + 31=>"平仓増を买います", + 32=>"倉庫が凍結する", + 34=>"通夜料", + 35=>"取引手数料", + 36=>"契約取引のキャンセル", + 37=>"通証両替契約貨幣の増加", + 38=>"事業体控除の申請", + 39=>"資産両替は両替を減らす", + 40=>"資産交換でUSDC資金を増やす", + 50 => '通貨取引', + 51 => '通貨取引', + 99=>"ユーザーが貨幣の引き出しを申請する", + 100=>"ユーザーの貨幣獲得成功", + 101=>"ユーザーの貨幣獲得に失敗しました", + 102=>"取引のキャンセル", + 103=>"取引のキャンセル", + 104=>"契約取引口座の変更", + 105=>"証明書の奨励", + 106=>"奨励デジタル通貨", + 107=>"通証両替USDC", + 108=>"バックグランド調整通証", + 299=>"契約取引口座の変更", + 401=>"振替", + 200=>"チャージの残高増加", + //c2c交易 + 201=>"ユーザーが資金売却を発表する", + 202=>"自動キャンセルc 2 c資金取引", + 203=>"ユーザー資金への売却", + 204=>"ユーザーの資金購入成功", + 205=>"事業者が資金売却の発表を撤回する", + 206=>"資金(c 2 c)転入契約", + 207=>"資金(c 2 c)転入契約", + 208=>"契約繰越資金(c 2 c)", + 209=>"契約繰越資金(c 2 c)", + 211=>"審査解凍契約で凍結しない", + 212=>"ヒストリカル損益解放、契約貨幣増加", + 501=>"オプション注文", + 502=>"オプション倉庫決済", + 600=>"フラッシュ減少残高", + 601=>"フラッシュを通して残高を増やす", + 602=>"フラッシュはロック残高を減らす", + 603=>"フラッシュはロック残高を増加します。", + 604=>"フラッシュは却下し、残高を増やす", +// +// 206=>"契約繰越オプション(c 2 c)", +// 207=>"契約繰越オプション(c 2 c)", +// 208=>"契約繰越オプション(c 2 c)", +// 209=>"契約繰越オプション(c 2 c)", +// 206=>"資金(c 2 c)繰越オプション", +// 207=>"資金(c 2 c)繰越オプション", +// 208=>"オプション繰越資金(c 2 c)", +// 209=>"オプション繰越資金(c 2 c)", +// 206=>"フラッシュバック契約", +// 207=>"フラッシュバック契約", +// 208=>"契約転入フラッシュ", +// 209=>"契約転入フラッシュ", + + 220=>"USDC両替bmb減少USDC", + 221=>"USDCがBMBに両替する手数料", + 230=>"ユーザーが保険を買う", + 231=>"ユーザーへの補償", + 232=>"ユーザーに賠償し、保証金額をクリアする", + 233=>"保険解約、保険金額クリア", + 234=>"保険解約、保険金額クリア", +// 234=>"保険解約、加入者の賠償", + 235=>"保険取引手数料の解放", + 250=>"部下が利益を取り戻す", + 251=>"貨幣を持つ", + 1001=>"契約換算契約", + 1002=>"契約換算契約", + 1003=>"購入契約控除", + 1004=>"ロックボックス", + 2022=>"SGDを申請する", + 2023=>"新しい通貨収入のサブスクリプション", + ]; + return $a[$value]??'Unknow Operation'; + + } + + public function user() + { + return $this->belongsTo('App\Users', 'user_id', 'id'); + } + + //关联钱包记录模型 + public function walletLog() + { + return $this->hasOne('App\WalletLog', 'account_log_id', 'id')->withDefault(); + } +} diff --git a/app/Currency.php b/app/Currency.php new file mode 100644 index 0000000..ced6d6f --- /dev/null +++ b/app/Currency.php @@ -0,0 +1,129 @@ +original; + $attributes = $this->attributes; + if( + $original['id'] != $attributes['id'] + ){//这些字段不准修改 + return false; + } + + if ($original['address_erc'] != $attributes['address_erc'] || + $original['address_omni'] != $attributes['address_omni']) { + // 修改地址时要判断二级密码 + $second_pwd = md5($_POST['second_pwd']); + if ($second_pwd != md5($this->second_pwd)) { + return false; + } + } + + //其他字段可以修改 + return true; + } + + public function quotation() + { + return $this->hasMany(CurrencyMatch::class, "legal_id", "id"); + } + public function microNumbers() + { + return $this->hasMany(MicroNumber::class)->orderBy("number", "asc"); + } + public function getCreateTimeAttribute() + { + return date("Y-m-d H:i:s", $this->attributes["create_time"]); + } + public static function getNameById($currency_id) + { + $array = self::find($currency_id); + $name=$array ? $array->name:''; + return $name; + } + public static function getCnyPrice($currency_id) + { + //$USDTRate = Setting::getValueByKey("USDTRate", 7.08); + $USDTRate = Excate::where('code', 'CNY')->value('num')??7.20; + $Currencys = Currency::where("name", "USDC")->select(["id"])->first(); + $MarketHours = MarketHour::orderBy("id", "desc")->where("currency_id", $currency_id)->where("legal_id", $Currencys->id)->first(); + if (!empty($MarketHours)) { + $result = $MarketHours->highest * $USDTRate; + } else { + $currency = Currency::where("id", $currency_id)->first(); + // file_put_contents('/www/wwwroot/amex.theice.vip/public/tt.txt',$currency_id."---".json_encode($currency)); + $result = $currency->price * $USDTRate; + } + if ($currency_id == $Currencys->id) { + $result = 1 * $USDTRate; + } + return $result; + } + public function getRmbRelationAttribute() + { + $hlOeRCQ = Excate::where('code', 'CNY')->value('num')??7.20; + //$hlOeRCQ = Setting::getValueByKey("USDTRate", 7.08); + return $hlOeRCQ; + } + public function getToPbPriceAttribute() + { + $dSsXLZQ = $this->id; + $hISyKGJ = Currency::where("name", UsersWallet::CURRENCY_DEFAULT)->first(); + $GqUwBMv = MarketHour::orderBy("id", "desc")->where("currency_id", $dSsXLZQ)->where("legal_id", $hISyKGJ->id)->first(); + if (!empty($GqUwBMv)) { + $wJethqJ = $GqUwBMv->highest; + } else { + $wJethqJ = $hISyKGJ->price; + } + if ($dSsXLZQ == $hISyKGJ->id) { + $wJethqJ = 1; + } + if($this->price==0 || $wJethqJ==0){ + $ylkngCv=0; + }else{ + $ylkngCv = bcdiv($this->price, $wJethqJ, 8); + } + + return $ylkngCv; + } + public static function getPbPrice($currency_id) + { + $zcKrDPQ = Currency::where("name", UsersWallet::CURRENCY_DEFAULT)->first(); + $BjBaFEv = MarketHour::orderBy("id", "desc")->where("currency_id", $currency_id)->where("legal_id", $zcKrDPQ->id)->first(); + if (!empty($BjBaFEv)) { + $rGYvahQ = $BjBaFEv->highest; + } else { + $rGYvahQ = $zcKrDPQ->price; + } + if ($currency_id == $zcKrDPQ->id) { + $rGYvahQ = 1; + } + return $rGYvahQ; + } + public function getOriginKeyAttribute($value) + { + $sZVuipJ = $this->attributes["key"] ?? ""; + return $sZVuipJ != "" ? decrypt($sZVuipJ) : ""; + } + public function getKeyAttribute($value) + { + return $value == "" ?: "********"; + } + public function setKeyAttribute($value) + { + if ($value != "") { + return $this->attributes["key"] = encrypt($value); + } + } +} \ No newline at end of file diff --git a/app/Http/mode/Sina.php b/app/Http/mode/Sina.php new file mode 100644 index 0000000..afd1e2d --- /dev/null +++ b/app/Http/mode/Sina.php @@ -0,0 +1,1332 @@ +$v){ + + + $data_arr[] = [ + "id" => strtotime($v['day']), + "period" => '1min', + "base-currency" => $name, + "quote-currency" => 'USDC', + "open" => $v['open'],//开 + "close" => $v['close'],//关 + "high" => $v['high'],//高 + "low" =>$v['low'],//低 + "vol" => $v['volume'],//交易量 + "amount" =>$v['amount']//数量 + ]; + }//777 + + + return $data_arr; + + } + + + + + public function real_gu($name){ + + $hq = +'{ + "msg": "ok", + "code": 1, + "data": { + "VPU": { + "after_price": "152.9300", + "volume_avg10": "180154", + "market_value": "6134400000", + "trade_time": "2024-05-24 04:00:00", + "change": "-2.7400", + "eps": "0.00", + "after_volume": "241", + "volume": "171928", + "shares": "40000000", + "after_change": "-0.43", + "high": "155.9400", + "update_time": "2024-05-24 09:46:10", + "low": "153.2800", + "pe": "--", + "price": "153.3600", + "name": "公用事业股ETF", + "dividend": "0.00", + "52week_low": "116.4040", + "after_changeRate": "-0.28", + "changeRate": "-1.76", + "preclose": "156.1000", + "open": "155.9400", + "52week_high": "158.0700", + "after_time": "2024-05-24 07:25:00" + } + }, + "time": 1716519177 +}'; + + $host = "http://finance.market.alicloudapi.com"; + $path = "/us/real"; + $method = "GET"; + $appcode = "38e9f1ff393246c6b9f3569512e1e5c4"; + $headers = array(); + array_push($headers, "Authorization:APPCODE " . $appcode); + $querys = "symbol=$name"; + $bodys = ""; + $url = $host . $path . "?" . $querys; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, 0); + if (1 == strpos("$".$host, "https://")) + { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + + $realhq = curl_exec($curl); + + + $data_array = json_decode($realhq,true); + // print_r($data_array);exit; + if($data_array['code']==1 && !empty($data_array['data'])){ + $str = $data_array['data'][$name]; + } + + + if($data_array['code']==0 || $realhq=='' || empty($data_array['data'])){ + $data_array = json_decode($hq,true); + + $str = $data_array['data']['VPU']; + } + + // print_r($data_array);exit; + + $info = DB::table('currency')->where('vcode',$name)->first(); + + $data = []; + $data['now_price'] = $str['price'];//最新价格 + $data['add_time'] = time(); + $data['change'] = $str['changeRate']; + $data['high'] = $str['high'];//最高 √ + $data['low'] = $str['low'];//最低 √ + $data['open'] = $str['open'];//开 √ + $data['close'] = $str['preclose'];//关 + $data['volume'] = $str['volume']; + + DB::table('currency_quotation')->where('currency_id',$info->id)->update($data); + // echo $info->id; + // print_r($data);exit; + } + + //k线类型, 1:1分钟,5:五分钟;15:15分钟;30:30分钟,60:60分钟,120:120分钟,240:日K,1200:周K,7200:月K,21600:季K,43200:半年K,86400:年K + //ETFGP + public function geteftgp($name, $peroid, $limit) + { + + $klinedemo='{ + "code": 1, + "data": [ + { + "volume": 322, + "high": "153.5900", + "amount": 49440.4, + "low": "153.5200", + "day": "2024-05-23 15:35:00", + "close": "153.5200", + "open": "153.5900" + }, + { + "volume": 557, + "high": "153.5000", + "amount": 85489, + "low": "153.4650", + "day": "2024-05-23 15:36:00", + "close": "153.4650", + "open": "153.5000" + }, + { + "volume": 402, + "high": "153.5550", + "amount": 61729.1, + "low": "153.5550", + "day": "2024-05-23 15:38:00", + "close": "153.5550", + "open": "153.5550" + }, + { + "volume": 718, + "high": "153.6099", + "amount": 110286, + "low": "153.5805", + "day": "2024-05-23 15:39:00", + "close": "153.6099", + "open": "153.6000" + }, + { + "volume": 300, + "high": "153.6000", + "amount": 46076.5, + "low": "153.5800", + "day": "2024-05-23 15:40:00", + "close": "153.5800", + "open": "153.6000" + }, + { + "volume": 241, + "high": "153.6100", + "amount": 37020, + "low": "153.6100", + "day": "2024-05-23 15:41:00", + "close": "153.6100", + "open": "153.6100" + }, + { + "volume": 417, + "high": "153.6200", + "amount": 64059.5, + "low": "153.6200", + "day": "2024-05-23 15:42:00", + "close": "153.6200", + "open": "153.6200" + }, + { + "volume": 462, + "high": "153.5550", + "amount": 70934.2, + "low": "153.4900", + "day": "2024-05-23 15:43:00", + "close": "153.4900", + "open": "153.5550" + }, + { + "volume": 196, + "high": "153.4851", + "amount": 30083.1, + "low": "153.4851", + "day": "2024-05-23 15:44:00", + "close": "153.4851", + "open": "153.4851" + }, + { + "volume": 135, + "high": "153.5400", + "amount": 20727.9, + "low": "153.5400", + "day": "2024-05-23 15:45:00", + "close": "153.5400", + "open": "153.5400" + }, + { + "volume": 850, + "high": "153.4700", + "amount": 130411, + "low": "153.3700", + "day": "2024-05-23 15:46:00", + "close": "153.3700", + "open": "153.4700" + }, + { + "volume": 525, + "high": "153.3650", + "amount": 80513.9, + "low": "153.3404", + "day": "2024-05-23 15:47:00", + "close": "153.3404", + "open": "153.3650" + }, + { + "volume": 1087, + "high": "153.3850", + "amount": 166703, + "low": "153.3400", + "day": "2024-05-23 15:48:00", + "close": "153.3850", + "open": "153.3600" + }, + { + "volume": 425, + "high": "153.4500", + "amount": 65215.2, + "low": "153.4450", + "day": "2024-05-23 15:50:00", + "close": "153.4450", + "open": "153.4500" + }, + { + "volume": 921, + "high": "153.5200", + "amount": 141360, + "low": "153.4300", + "day": "2024-05-23 15:51:00", + "close": "153.4300", + "open": "153.5200" + }, + { + "volume": 303, + "high": "153.4950", + "amount": 46506.5, + "low": "153.4700", + "day": "2024-05-23 15:52:00", + "close": "153.4950", + "open": "153.4700" + }, + { + "volume": 386, + "high": "153.4700", + "amount": 59236.3, + "low": "153.4500", + "day": "2024-05-23 15:53:00", + "close": "153.4700", + "open": "153.4600" + }, + { + "volume": 683, + "high": "153.5150", + "amount": 104849, + "low": "153.4950", + "day": "2024-05-23 15:54:00", + "close": "153.5150", + "open": "153.4950" + }, + { + "volume": 1022, + "high": "153.5200", + "amount": 156869, + "low": "153.4700", + "day": "2024-05-23 15:55:00", + "close": "153.5100", + "open": "153.5200" + }, + { + "volume": 4004, + "high": "153.5000", + "amount": 614144, + "low": "153.2800", + "day": "2024-05-23 15:56:00", + "close": "153.3850", + "open": "153.5000" + }, + { + "volume": 202, + "high": "153.3900", + "amount": 30984.8, + "low": "153.3900", + "day": "2024-05-23 15:57:00", + "close": "153.3900", + "open": "153.3900" + }, + { + "volume": 597, + "high": "153.4550", + "amount": 91582.4, + "low": "153.3700", + "day": "2024-05-23 15:58:00", + "close": "153.4550", + "open": "153.3700" + }, + { + "volume": 3067, + "high": "153.4700", + "amount": 470600, + "low": "153.4100", + "day": "2024-05-23 15:59:00", + "close": "153.4200", + "open": "153.4200" + }, + { + "volume": 2310, + "high": "153.4600", + "amount": 354412, + "low": "153.3400", + "day": "2024-05-23 16:00:00", + "close": "153.4400", + "open": "153.4600" + } + ], + "message": "OK" +}'; + + + + $types=240; + if($peroid=="1D") $types=240; + if($peroid=="1min") $types=1; + if($peroid=="5min") $types=5; + if($peroid=="15min") $types=15; + if($peroid=="30min") $types=30; + if($peroid=="60min") $types=60; + if($peroid=="120min") $types=120; + if($peroid=="1hour") $types=60; + if($peroid=="1week") $types=1200; + if($peroid=="1mon") $types=7200; + if($peroid=="1year") $types=86400; + if($peroid=="1M") $types=1200; + if($peroid=="1W") $types=7200; + + $host = "http://finance.market.alicloudapi.com"; + $path = "/us/kline"; + $method = "GET"; + $appcode = "38e9f1ff393246c6b9f3569512e1e5c4"; + $headers = array(); + array_push($headers, "Authorization:APPCODE " . $appcode); + $querys = "symbol=".$name."&type=".$types."&limit=".$limit; + $bodys = ""; + $url = $host . $path . "?" . $querys; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, 0); + if (1 == strpos("$".$host, "https://")) + { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + + $kline = curl_exec($curl); + + + $data_array = json_decode($kline,true); + + // file_put_contents('/www/wwwroot/crypto/public/w2.txt',json_encode($data_array).PHP_EOL,FILE_APPEND); + + + if($data_array['code']==0 || empty($data_array['data'])) $data_array = json_decode($klinedemo,true); + + $str2 = $data_array['data']; + foreach ($str2 as $k=>$v){ + + + $data_arr[] = [ + "id" => strtotime($v['day']), + "period" => $peroid, + "base-currency" => $name, + "quote-currency" => 'USDC', + "open" => $v['open'],//开 + "close" => $v['close'],//关 + "high" => $v['high'],//高 + "low" =>$v['low'],//低 + "vol" => $v['volume'],//交易量 + "amount" =>$v['amount']//数量 + ]; + }//777 + + + return $data_arr; + + + } + + + //外汇 + public function getKline($name, $peroid, $limit) + { + $types=240; + if($peroid=="1D") $types=0; + if($peroid=="1min") $types=1; + if($peroid=="5min") $types=5; + if($peroid=="15min") $types=15; + if($peroid=="30min") $types=30; + if($peroid=="60min") $types=60; + if($peroid=="1hour") $types=60; + if($peroid=="1week") $types=120; + if($peroid=="1mon") $types=240; + if($peroid=="1year") $types=240; + if($peroid=="1M") $types=0; + if($peroid=="1W") $types=0; + $host = "http://finance.market.alicloudapi.com"; + $path = "/waihui/kline"; + $method = "GET"; + $appcode = "38e9f1ff393246c6b9f3569512e1e5c4"; + $headers = array(); + array_push($headers, "Authorization:APPCODE " . $appcode); + // $querys = "symbol=".$name; + $querys = "symbol=".$name."&type=".$types."&limit=".$limit; + $bodys = ""; + $url = $host . $path . "?" . $querys; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, 0); + if (1 == strpos("$".$host, "https://")) + { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + $res=curl_exec($curl); + $res = json_decode($res, true); + $data_arr = []; + if (!isset($res['data']['lines'])) { + return []; + } + + foreach ($res['data']['lines'] as $key => $item) { + $data_arr[] = [ + "id" => $item[6], + "period" => $peroid, + "base-currency" =>$name, + "quote-currency" =>'USDC', + "open" => $item[0], + "close" => $item[1], + "high" => $item[2], + "low" => $item[3], + "vol" => 0, + "amount" => $item[0] + ]; + + // $res1 = array_reverse($data_arr); + } + + return $data_arr; + +} + //贵金属 + public function getwaipanKline($name, $peroid, $limit) + { + + $types=240; + if($peroid=="1D") $types=0; + if($peroid=="1min") $types=1; + if($peroid=="5min") $types=5; + if($peroid=="15min") $types=15; + if($peroid=="30min") $types=30; + if($peroid=="60min") $types=60; + if($peroid=="1hour") $types=60; + if($peroid=="1week") $types=120; + if($peroid=="1mon") $types=240; + if($peroid=="1year") $types=240; + if($peroid=="1M") $types=0; + if($peroid=="1W") $types=0; + + $host = "http://finance.market.alicloudapi.com"; + $path = "/waipan/kline"; + $method = "GET"; + $appcode = "38e9f1ff393246c6b9f3569512e1e5c4"; + $headers = array(); + array_push($headers, "Authorization:APPCODE " . $appcode); + // $querys = "symbol=".$name; + $querys = "symbol=".$name."&type=".$types."&limit=".$limit; + $bodys = ""; + $url = $host . $path . "?" . $querys; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, 0); + if (1 == strpos("$".$host, "https://")) + { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + $res = curl_exec($curl); + + $res = json_decode($res, true); + $data_arr = []; + if (!isset($res['data']['lines'])) { + return []; + } + + foreach ($res['data']['lines'] as $key => $item) { + $data_arr[] = [ + "id" => $item[7], + "period" => $peroid, + "base-currency" =>$name, + "quote-currency" =>'USDC', + "open" => $item[0], + "close" => $item[1], + "high" => $item[2], + "low" => $item[3], + "vol" => $item[6], + "amount" => $item[0] + ]; + + // $res1 = array_reverse($data_arr); + } + + return $data_arr; + +} + + + + + + public function sina($name){ + $code = $name; + $time = date('Y_m_d',time()); + //preg_match_all("/[a-zA-Z]{1}/",$code,$arrAl); + //echo "字母个数:".count($arrAl[0])."
"; +$url = "https://stock2.finance.sina.com.cn/futures/api/openapi.php/GlobalFuturesService.getGlobalFuturesMinLine?symbol=$code&callback=var%20t1hf_W=";//分k + //$url = "https://gu.sina.cn/ft/api/jsonp.php/var%20_W_5_1663703010461=/GlobalService.getMink?symbol=XAU&type=5";//5分 + header('Connection: Upgrade'); + header('Pragma: no-cache'); + header('Cache-Control: no-cache'); + header('Accept-Encoding: gzip, deflate, br'); + header('Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'); + header('User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36'); + $html = html_entity_decode(file_get_contents("$url")); + $str2 = substr($html, 61); + $str2 = substr_replace($str2,"",-2,2); + $str2 = json_decode($str2,true); + $str2 = $str2['result']['data']['minLine_1d']; + // echo json_encode($str2);exit; + foreach ($str2 as $k=>$v){ + if($k>0){//777 + /*应甲方要求,个别前端有问题,进行数据修改,不要删改,不然前端有意想不到的惊喜*/ + if($name=="NG"||$name=="XPD"){ + $rand = '0.0'.rand(rand(1,3),rand(5,9)); + $rand1 = '0.0'.rand(rand(1,3),rand(5,9)); + $rand2 = '0.0'.rand(rand(1,3),rand(5,9)); + $rand3 = '0.0'.rand(rand(1,3),rand(5,9)); + + }else{ + $rand = '0.00'.rand(rand(1,3),rand(5,9)); + $rand1 = '0.00'.rand(rand(1,3),rand(5,9)); + $rand2 = '0.00'.rand(rand(1,3),rand(5,9)); + $rand3 = '0.00'.rand(rand(1,3),rand(5,9)); + + } + + if(rand(1,2)==1){ + $open = $v[1]/100*$rand3+$v[1]; + + }else + { + $open = $v[1]-$v[1]/100*$rand3; + + } + + if(rand(1,2)==1) + { + $close = $v[1]-$v[1]/100*$rand2; + + }else{ + $close = $v[1]-$v[1]/100*$rand2; + + } + /**/ + if($k==count($str2)-1){ + $info = DB::table('currency')->where('name',$name)->first(); + $info = json_encode($info); + $info = json_decode($info,true); + $bi = DB::table('currency_quotation')->where('currency_id',$info['id'])->first(); + $bi = json_encode($bi); + $bi = json_decode($bi,true); + $close = $bi['now_price']; + } + $data_arr[] = [ + "id" => strtotime($v[5]), + "period" => '1min', + "base-currency" => $name, + "quote-currency" => 'USDC', + "open" => $open,//开 + "close" => $close,//关 + "high" => $v[1]+$v[1]/100*$rand1,//高 + "low" =>$v[1]-$v[1]/100*$rand,//低 + "vol" => 0,//交易量 + "amount" => 0//数量 + ]; + }//777 + } + //return array_reverse($data_arr); + return $data_arr; + } + //外汇 + public function foreign($name){ + + + $result =DB::table('currency')->where('name',$name)->first(); + $code = $result->vcode; + + + $time = date('Y_m_d',time()); + $url = "https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20_fx_susdcad_1_1708783212908=/NewForexService.getMinKline?symbol=$code&scale=1&datalen=1440" ;//分k + header('Connection: Upgrade'); + header('Pragma: no-cache'); + header('Cache-Control: no-cache'); + header('Accept-Encoding: gzip, deflate, br'); + header('Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'); + header('User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36'); + $html = html_entity_decode(file_get_contents("$url")); + $str2 = substr($html, 82); + $str2 = substr_replace($str2,"",-2,2); + $str2 = json_decode($str2,true); + foreach ($str2 as $k=>$v){ + if($k>0){//777 + /*应甲方要求,个别前端有问题,进行数据修改,不要删改,不然前端有意想不到的惊喜*/ + if($name=="GBP"||$name=="NZD"||$name=="EUR"){ + $rand = '0.00'.rand(rand(1,3),rand(5,9)); + $rand1 = '0.00'.rand(rand(1,3),rand(5,9)); + $rand2 = '0.00'.rand(rand(1,3),rand(5,9)); + $rand3 = '0.00'.rand(rand(1,3),rand(5,9)); + if(rand(1,2)==1){ + $open = $v['o']/100*$rand3+$v['o']; + + }else{ + $open = $v['o']-$v['o']/100*$rand3; + + } + + if(rand(1,2)==1){ + $close = $v['o']-$v['o']/100*$rand2; + + }else + { + $close = $v['o']-$v['o']/100*$rand2; + + } + + }else{ + $open = $v['o']; + $close = $v['c']; + + } + /**/ + + if($k==count($str2)-1){ + $info = DB::table('currency')->where('name',$name)->first(); + $info = json_encode($info); + $info = json_decode($info,true); + $bi = DB::table('currency_quotation')->where('currency_id',$info['id'])->first(); + $bi = json_encode($bi); + $bi = json_decode($bi,true); + $close = $bi['now_price']; + } + + $data_arr[] = [ + "id" => strtotime($v['d']), + "period" => '1min', + "base-currency" => $name, + "quote-currency" => 'USDC', + "open" => $open,//开 + "close" => $close,//关 + "high" => $v['h'],//高 + "low" =>$v['l'],//低 + "vol" => $v['o'],//交易量 + "amount" => $v['o']//数量 + ]; + } + } + //return array_reverse($data_arr); + return $data_arr; + } + + + //内部调用实时采集价格 + public function real_s($name){ + $hq = '{ + "msg": "ok", + "code": 1, + "data": { + "change": "0.3800", + "ask_vol": "0", + "bid_vol": "0", + "hold": "0", + "volume": 0, + "high": "2339.64", + "update_time": 1719582600, + "low": "2318.94", + "price": "2327.71", + "name": "伦敦金(现货黄金)", + "ask": "2328.06", + "changeRate": "0.0163", + "preclose": "2327.33", + "bid": "2327.71", + "open": "2327.53" + }, + "time": 1719582646 +}'; + + + $host = "http://finance.market.alicloudapi.com"; + $path = "/waipan/real"; + $method = "GET"; + $appcode = "38e9f1ff393246c6b9f3569512e1e5c4"; + $headers = array(); + array_push($headers, "Authorization:APPCODE " . $appcode); + $querys = "symbol=$name"; + $bodys = ""; + $url = $host . $path . "?" . $querys; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, 0); + if (1 == strpos("$".$host, "https://")) + { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + + $realhq = curl_exec($curl); + + + $data_array = json_decode($realhq,true); + + if($data_array['code']==1 && !empty($data_array['data'])){ + $str = $data_array['data']; + } + if($data_array['code']==0 || $realhq=='' || empty($data_array['data'])){ + $data_array = json_decode($hq,true); + + $str = $data_array['data']; + } + + // print_r($data_array);exit; + + $info = DB::table('currency')->where('vcode',$name)->first(); + + $data = []; + $data['now_price'] = $str['price'];//最新价格 + $data['add_time'] = time(); + $data['change'] = $str['changeRate']; + $data['high'] = $str['high'];//最高 √ + $data['low'] = $str['low'];//最低 √ + $data['open'] = $str['open'];//开 √ + $data['close'] = $str['preclose'];//关 + $data['volume'] = $str['volume']; + + DB::table('currency_quotation')->where('currency_id',$info->id)->update($data); + // echo $info->id; + // print_r($data);exit; + } + + + + + + + + + + + //内部调用实时采集价格 + public function real_s_sina($name){ + $curl = curl_init(); + curl_setopt_array($curl, array( + CURLOPT_URL => 'https://w.sinajs.cn/?_=0.6314213010647229&list=hf_'.$name, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_HTTPHEADER => array( + 'referer: https://finance.sina.com.cn/' + ), +)); + $response = curl_exec($curl); + curl_close($curl); +// file_put_contents('/www/wwwroot/crypto/public/w.txt',$name."--".$response); + preg_match_all("/[a-zA-Z]{1}/",$name,$arrAl); + $str2 = substr($response, 16+count($arrAl[0])); + $str2 = substr_replace($str2,"",-3,2); + //echo $str2; + $str = explode(',',$str2); + //$str[0];//最新价格 $str[4];最高价 $str[5];最低价 + $info = DB::table('currency')->where('name',$name)->first(); + $info = json_encode($info); + $info = json_decode($info,true); + if(round(100-round($str[0]/$info['price']*100,2),2)>0){ + $chanhe = '+'.round(100-round($str[0]/$info['price']*100,2),2); + }else{ + $chanhe = round(100-round($str[0]/$info['price']*100,2),2); + } + $data['now_price'] = $str[0];//最新价格 + $data['add_time'] = time(); + $data['change'] = bcdiv($chanhe,100,2); + $data['high'] = $str[4];//最高 √ + $data['low'] = $str[5];//最低 √ + $data['open'] = $str[8];//开 √ + $data['close'] = $str[0];//关 + $data['volume'] = $str[9];//交易量 + DB::table('currency_quotation')->where('currency_id',$info['id'])->update($data); + //DB::table('currency')->where('id',$info['id'])->update(['price'=>$str[0]]); + } + //实时采集期货价格 + public function real(){ + //$this->real_s('XAU');exit; + //$this->real_s($name); + $list = DB::table('currency_matches')->where('market_from',3)->paginate(100); + $list = json_encode($list); + $list = json_decode($list,true); + $l = array(); + foreach ($list['data'] as $k=>$v){ + $info = DB::table('currency')->where('id',$v['currency_id'])->first(); + $info = json_encode($info); + $info = json_decode($info,true); + $this->real_s($info['vcode']); + } + /// echo 'success'; + } + + + + //实时采集股票价格 + public function gpreal(){ + //$this->real_s('XAU');exit; + //$this->real_s($name); + $list = DB::table('currency_matches')->where('market_from',6)->paginate(100); + + $list = json_encode($list); + $list = json_decode($list,true); + $l = array(); + + foreach ($list['data'] as $k=>$v){ + $info = DB::table('currency')->where('id',$v['currency_id'])->first(); + + $this->real_gu($info->vcode); + } + // echo 'success'; + } + + //实时采集股票价格 + public function etfreal(){ + //$this->real_s('XAU');exit; + //$this->real_s($name); + $list = DB::table('currency_matches')->where('market_from',9)->paginate(100); + $list = json_encode($list); + $list = json_decode($list,true); + $l = array(); + foreach ($list['data'] as $k=>$v){ + $info = DB::table('currency')->where('id',$v['currency_id'])->first(); + + $this->real_gu($info->vcode); + } + // echo 'success'; + } + + + //实时采集外汇价格 + public function foreign_real(){ + $list = DB::table('currency_matches')->where('market_from',0)->paginate(100); + $list = json_encode($list); + $list = json_decode($list,true); + $l = array(); + foreach ($list['data'] as $k=>$v){ + $info = DB::table('currency')->where('id',$v['currency_id'])->first(); + $info = json_encode($info); + $info = json_decode($info,true); + $this->foreign_s($info['real_name']); + } + // echo 'success'; + } + + //外汇实时采集 + //内部调用实时采集价格 + public function foreign_s($name){ + // $name = strtolower($name); + + $hq ='{ + "msg": "ok", + "code": 1, + "data": { + "EURUSD": { + "change": "-0.000220", + "update_time": 1719582553, + "bofu": "0.00348", + "high": "1.071990", + "low": "1.068510", + "price": "1.070210", + "name": "欧元兑美元即期汇率", + "ask": "1.070230", + "bid": "1.070210", + "preclose": "1.070430", + "changeRate": "-0.020000", + "open": "1.070470", + "zhenfu": "0.3251" + } + }, + "time": 1719582560 +}'; + + + $host = "http://finance.market.alicloudapi.com"; + $path = "/waihui/real"; + $method = "GET"; + $appcode = "38e9f1ff393246c6b9f3569512e1e5c4"; + $headers = array(); + array_push($headers, "Authorization:APPCODE " . $appcode); + $querys = "symbol=".$name; + $bodys = ""; + $url = $host . $path . "?" . $querys; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, 0); + if (1 == strpos("$".$host, "https://")) + { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + $realhq = curl_exec($curl); + + + $data_array = json_decode($realhq,true); + // file_put_contents('/www/wwwroot/crypto/public/w2.txt',json_encode($realhq)."--".json_encode($data_array).PHP_EOL,FILE_APPEND); + if($data_array['code']==1 && !empty($data_array['data'])){ + $str = $data_array['data'][$name]; + } + if($data_array['code']==0 || $realhq=='' || empty($data_array['data'])){ + $data_array = json_decode($hq,true); + + $str = $data_array['data']['EURUSD']; + } + + + + // print_r($data_array);exit; + + $info = DB::table('currency')->where('real_name',$name)->first(); + + $data = []; + $data['now_price'] = $str['price'];//最新价格 + $data['add_time'] = time(); + $data['change'] = $str['changeRate']; + $data['high'] = $str['high'];//最高 √ + $data['low'] = $str['low'];//最低 √ + $data['open'] = $str['open'];//开 √ + $data['close'] = $str['preclose'];//关 + $data['volume'] = 0; + + + + DB::table('currency_quotation')->where('currency_id',$info->id)->update($data); + + + } + + + //外汇实时采集 + //内部调用实时采集价格 + public function foreign_s_sina($name){ + // $name = strtolower($name); + + $result =DB::table('currency')->where('name',$name)->first(); + $code = $result->vcode; + $curl = curl_init(); + curl_setopt_array($curl, array( + CURLOPT_URL => 'https://w.sinajs.cn/?_=0.27948490427865&list='.$code.',sys_time', + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_HTTPHEADER => array( + 'referer: https://finance.sina.com.cn/' + ), +)); + $response = curl_exec($curl); + curl_close($curl); + preg_match_all("/[a-zA-Z]{1}/",$name,$arrAl); + $str2 = substr($response, 20+count($arrAl[0])); + $str2 = substr_replace($str2,"",-37,37); + //echo $str2;exit; + $str = explode(',',$str2); + $name = ucfirst($name); + $info = DB::table('currency')->where('name',$name)->first(); + $info = json_encode($info); + $info = json_decode($info,true); + + if(round(100-round($str[1]/$info['price']*100,4),4)>0){ + $chanhe = '+'.round(100-round($str[1]/$info['price']*100,4),4); + }else{ + $chanhe = round(100-round($str[1]/$info['price']*100,4),4); + } + $data['now_price'] = $str[1];//最新价格 + $data['add_time'] = time(); + $data['change'] = bcdiv($chanhe,100,2); + $data['high'] = $str[3];//最高 √ + $data['low'] = $str[5];//最低 √ + $data['open'] = $str[6];//开 √ + $data['close'] = $str[1];//关 + $data['volume'] = $info['price']*rand(100,1000); + DB::table('currency_quotation')->where('currency_id',$info['id'])->update($data); + //DB::table('currency')->where('id',$info['id'])->update(['price'=>$str[1]]); + } + +} \ No newline at end of file diff --git a/app/Users.php b/app/Users.php new file mode 100644 index 0000000..32531ae --- /dev/null +++ b/app/Users.php @@ -0,0 +1,452 @@ + '亏损', + MicroOrder::RESULT_BALANCE => '无', + MicroOrder::RESULT_PROFIT => '盈利', + ]; + + public function getUserrealNameAttribute() + { + $user_profile = $this->userReal()->first(); + if($user_profile){ + return $user_profile->name ?? '--'; + }else{ + return '--'; + } + + } + + public function userReal() + { + return $this->hasMany(UserReal::class, 'user_id')->where('review_status', 2); + } + + public function userProfile() + { + return $this->hasOne(UserProfile::class, 'user_id'); + } + + public function getLeverBalanceAttribute() + { + $id = $this->getAttribute['id']; + if(empty($id)){ + return ''; + } + $wallet = UsersWallet::where('user_id', $id)->where('currency', 3)->first(); + return $wallet->lever_balance; + } + public function getLockLeverBalanceAttribute() + { + $id = $this->getAttribute['id']; + if(empty($id)){ + return ''; + } + $wallet = UsersWallet::where('user_id', $id)->where('currency', 3)->first(); + return $wallet->lock_lever_balance; + } + public function getLegalBalanceAttribute() + { + $id = $this->getAttribute['id']; + if(empty($id)){ + return ''; + } + $wallet = UsersWallet::where('user_id', $id)->where('currency', 3)->first(); + return $wallet->legal_balance; + } + public function getLockLegalBalanceAttribute() + { + $id = $this->getAttribute['id']; + $wallet = UsersWallet::where('user_id', $id)->where('currency', 3)->first(); + return $wallet->lock_legal_balance; + } + public function getUsdtMicAttribute() + { + $value = $this->getAttribute['id']; + if(empty($value)){ + return ''; + } + $us = DB::table('currency')->where('name', 'USDC')->first(); + + $wal = UsersWallet::where('currency', $us->id)->where('user_id', $value)->first(); + + return isset($wal->micro_balance) ? $wal->micro_balance : '0.00000'; + } + //期权账号 + public function getUsdtAttribute() + { + $value = $this->getAttributes['id']; + if(empty($value)){ + return ''; + } + $us = DB::table('currency')->where('name', 'USDC')->first(); + + $wal = UsersWallet::where('currency', $us->id)->where('user_id', $value)->first(); + + return isset($wal->lever_balance) ? $wal->lever_balance : '0.00000'; + } + + public function getCautionMoneyAttribute() + { + $value = $this->getAttributes['id']; + if(empty($value)){ + return ''; + } + return DB::table('lever_transaction')->where('user_id', $value)->whereIn('status', [0, 1])->sum('caution_money'); + } + + public function getParentNameAttribute() + { + $value = $this->getAttribute('agent_note_id'); + $p = Agent::where('id', $value)->first(); + return isset($p->username) ? $p->username : '-/-'; + } + + public function getMyAgentLevelAttribute() + { + $value = $this->attributes['agent_id'] ?? 0; + if ($value == 0) { + return '普通用户'; + } else { + $m = DB::table('agent')->where('id', $value)->first(); + $name = ''; + if (empty($m)) { + $name = ''; + } else { + if ($m->level == 0) { + $name = '超管'; + } else if ($m->level > 0) { + $name = $m->level . '级代理商'; + } + } + + return $name; + } + } + + // 修改用户积分 + public function ChangeScore($num,$model,$id,$remarks) + { + + $model->score -= $num; + if (!$model->save()){ + return true; + } + // 保存积分日志 + $log = [ + 'user_id' => $id, + 'type' => 2, + 'change' => -$num, + 'remarks' => $remarks, + 'create_time' => date('Y-m-d H:i:s',time()), + ]; + $res = DB::table('score_log')->insert($log); + if (empty($res)){ + return false; + } + +} + public function getCreateDateAttribute() + { + $value = $this->getAttribute('time'); + return $value; + return date('Y-m-d H:i:s', $value); + } + + //密码加密 + public static function MakePassword($password, $type = 0) + { + if ($type == 0) { + $salt = 'ABCDEFG'; + $passwordChars = str_split($password); + foreach ($passwordChars as $char) { + $salt .= md5($char); + } + } else { + $salt = 'TPSHOP' . $password; + } + return md5($salt); + } + + public static function getByAccountNumber($account_number) + { + return self::where('account_number', $account_number)->first(); + } + + public static function getByString($string) + { + if (empty($string)) { + return ""; + } + return self::where("phone", $string) + ->orwhere('email', $string) + ->orWhere('account_number', $string) + ->first(); + } + + public static function getById($id) + { + if (empty($id)) { + return ""; + } + return self::where("id", $id)->first(); + } + //生成邀请码 + public static function getExtensionCode() + { + $code = self::generate_password(4); + if (self::where("extension_code", $code)->first()) { + //如果生成的邀请码存在,继续生成,直到不存在 + $code = self::getExtensionCode(); + } + return $code; + } + public static function generate_password($length = 8) + { + $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; + $password = ""; + for ($i = 0; $i < $length; $i++) { + $password .= $chars[mt_rand(0, strlen($chars) - 1)]; + } + return $password; + } + + public static function getUserId() + { + // return session('user_id'); + $token = Token::getToken(); + $user_id = Token::getUserIdByToken($token); + return $user_id; + } + + public static function getAuthUser() + { + return self::find(self::getUserId()); + } + + + public function getTimeAttribute() + { + if (isset($this->attributes['time'])) { + $value = $this->attributes['time']; + return $value ? date('Y-m-d H:i:s', $value) : ''; + } else { + return ""; + } + } + + //获取用户的账号 手机号或邮箱 + public function getAccountAttribute() + { + //$value = $this->attributes['phone']; + $value = $this->getAttribute('phone'); + if (empty($value)) { + $value = $this->getAttribute['email']; + if(empty($value)){ + return ''; + } + $n = strripos($value, '@'); + $value = mb_substr($value, 0, 2) . '******' . mb_substr($value, $n); + } else { + $value = mb_substr($value, 0, 3) . '******' . mb_substr($value, -3, 3); + } + return $value; + } + + /* + //手势密码序列化 + public function setGesturePassword($value) { + $this->attributes['gesture_password'] = serialize($value); + } + //取出数据时反序列化 + public function getGesturePassword($value) { + return unserialize($value); + } + */ + + public function getIsSellerAttribute() + { + $id=$this->getAttribute['id']; + if(empty($id)){ + return 0; + } + $seller = Seller::where('user_id', $this->getAttribute['id'])->first(); + if (!empty($seller)) { + return 1; + } + return 0; + } + + public function cashinfo() + { + return $this->belongsTo('App\UserCashInfo', 'id', 'user_id'); + } + + public function legalDeal() + { + return $this->hasOne('App\C2cDeal', 'seller_id', 'id'); + } + + /** + * + * @param $model 用户模型实例 + * @param $status 锁定开关 + * @param $time 锁定结束时间 + * @return bool + */ + public function lockUser($model, $status, $time, $frozen_funds) + { + if (!empty($time)) { + $time = strtotime($time); + } + if ($status == 1) { + $model->status = 1; + $model->lock_time = $time; + } else { + $model->status = 0; + $model->lock_time = 0; + } + + if($frozen_funds==1){ + $model->frozen_funds = 1; + $model->lock_time = $time; + }else{ + $model->frozen_funds = 0; + $model->lock_time = 0; + } + $result = $model->save(); + if ($result) { + return true; + } + return false; + } + + public function getRiskNameAttribute() + { + $risk = $this->attributes['risk'] ?? 0; + return self::$roleList[$risk]; + } + + /* + * count 当前几代 + * $algebra 总共几代 + * user_id 用户id + * touch_user_id 触发者id + * currency 币种id + * price 金额 + * */ + public static function rebate($user_id,$touch_user_id,$currency,$price,$count=1,$algebra=0) + { + $user=self::where('id', $user_id)->first(); + $touch_user = self::getById($touch_user_id); + if (empty($user)) { + return true; + } + + if ($user->parent_id==0) { + return true; + } + $wallet = UsersWallet::where('currency', $currency) + ->where('user_id', $user->parent_id) + ->first(); + + $u_algebra=Algebra::where('algebra', $count)->first(); + if (empty($u_algebra)||empty($wallet)) { + $count+=1; + $algebra-=1; + $result=self::rebate($user->parent_id, $touch_user_id, $currency, $price, $count, $algebra); + return $result; + } + + $totle_price=$price*$u_algebra->rate/100; + $info='第'.$count."代用户{$touch_user->account_number}返手续费:".$totle_price; + $result = change_wallet_balance($wallet, 4, $totle_price, AccountLog::MICRO_TRADE_CLOSE_SETTLE, $info); + $algebra-=1; + $user_algebra=new UserAlgebra(); + $user_algebra->user_id=$user->parent_id; + $user_algebra->touch_user_id=$touch_user_id; + $user_algebra->algebra=$count; + $user_algebra->info=$info; + $user_algebra->value=$totle_price; + $user_algebra->save(); + $count+=1; + if ($algebra==0) { + return true; + }else{ + $result=self::rebate($user->parent_id, $touch_user_id, $currency, $price, $count, $algebra); + return $result; + } + + } + + public function belongAgent() + { + return $this->belongsTo(Agent::class, 'agent_note_id', 'id'); + } + + public static function gen_invite_code($length = 8) + { + $pattern = '0123456789'; + $code = self::gen_comm($pattern, $length); + $users = self::where('id', $code)->first(); + if ($users) { + return self::gen_invite_code($length); + } else { + return $code; + } + } + + private static function gen_comm($content, $length) + { + $key = ''; + for ($i = 0; $i < $length; $i++) { + $key .= $content[mt_rand(0, strlen($content) - 1)]; + } + + return $key; + } +} diff --git a/app/UsersWallet.php b/app/UsersWallet.php new file mode 100644 index 0000000..0e75002 --- /dev/null +++ b/app/UsersWallet.php @@ -0,0 +1,235 @@ +attributes['create_time']; + return $value ? date('Y-m-d H:i:s', $value) : ''; + } + + public function getCurrencyTypeAttribute() + { + return $this->hasOne('App\Currency', 'id', 'currency')->value('type'); + } + + + public function getCurrencyNameAttribute() + { + return $this->currencyCoin()->value('name'); + } + + public function getIsLegalAttribute() + { + return $this->currencyCoin()->value('is_legal'); + } + + public function getIsLeverAttribute() + { + return $this->currencyCoin()->value('is_lever'); + } + + public function getIsMatchAttribute() + { + return $this->currencyCoin()->value('is_match'); + } + + public function getIsMicroAttribute() + { + return $this->currencyCoin()->value('is_micro'); + } + + public function currencyCoin() + { + return $this->belongsTo(Currency::class, 'currency', 'id'); + } + + public static function MmakeWallet($user_id) + { + + $init_balance = Setting::getValueByKey('init_balance'); + + + self::insert([ + 'currency' => 3, + 'user_id' => $user_id, + 'change_balance' => $init_balance, + 'address' => null, + 'create_time' => time() + ]); + + $currency = Currency::where('is_legal',1)->orderBy('sort', 'asc')->get(); + foreach ($currency as $key => $value) { + $res = self::where([ + 'currency' => $value->id, + 'user_id' => $user_id + ])->first(); + if(!$res){ + self::insert([ + 'currency' => $value->id, + 'user_id' => $user_id, + 'address' => null, + 'create_time' => time() + ]); + } + + } + + + return true; + } + + + public static function makeWalletold($user_id) + { + // $currency = Currency::all(); + $currency = Currency::where('is_legal',1)->orderBy('sort', 'asc')->get(); + foreach ($currency as $key => $value) { + $res = self::where([ + 'currency' => $value->id, + 'user_id' => $user_id + ])->first(); + if(!$res){ + self::insert([ + 'currency' => $value->id, + 'user_id' => $user_id, + 'address' => null, + 'create_time' => time() + ]); + } + + } + return true; + } + + + public static function makeWallet($user_id) + { + + $currency = Currency::where('is_legal',1)->orderBy('sort', 'asc')->get(); + foreach ($currency as $key => $value) { + $res = self::where([ + 'currency' => $value->id, + 'user_id' => $user_id + ])->first(); + if(!$res){ + self::insert([ + 'currency' => $value->id, + 'user_id' => $user_id, + 'address' => null, + 'create_time' => time() + ]); + } + + } + + + return true; + } + public static function makeWalletbak($user_id) + { + $currency = Currency::all(); + + foreach ($currency as $key => $value) { + $res = self::where([ + 'currency' => $value->id, + 'user_id' => $user_id + ])->first(); + if(!$res){ + self::insert([ + 'currency' => $value->id, + 'user_id' => $user_id, + 'address' => null, + 'create_time' => time() + ]); + } + + } + return true; + } + + public static function getAddress(UsersWallet $wallet){ + $saveFlag = false; + + if($wallet->currency == 3){ + + $return = ['omni'=>$wallet->address_2,'erc20' => $wallet->address]; + }else{ + + + $return = $wallet->address; + } + + return $return; + } + + + public static function getUsdtWallet($userId){ + return self::where("user_id", $userId) + ->where("currency", 3) + ->first(); + } + + public static function getDF1Wallet($userId){ + $res = self::where("user_id", $userId) + ->where("currency", 29) + ->first(); + return $res; + } + + public function getCurrencyLogoAttribute() + { + return $this->currencyCoin()->value('logo'); + } + + + public function getUsdtPriceAttribute() + { + return $this->currencyCoin()->value('price') ?? 1; + } + + public function getPbPriceAttribute() + { + $currency_id = $this->attributes['currency']; + return Currency::getPbPrice($currency_id); + } + + public function getCnyPriceAttribute() + { + $currency_id = $this->attributes['currency']; + return Currency::getCnyPrice($currency_id); + } + + public function user() + { + return $this->belongsTo(Users::class, 'user_id', 'id'); + } + + public function getPrivateAttribute($value) + { + + return empty($value) ? '' : decrypt($value); + } + public function setPrivateAttribute($value) + { + $this->attributes['private'] = encrypt($value); + } + + public function getAccountNumberAttribute($value) + { + return $this->user()->value('account_number') ?? ''; + } +} diff --git a/app/Utils/Workerman/WsConnection.php b/app/Utils/Workerman/WsConnection.php new file mode 100644 index 0000000..5d653f1 --- /dev/null +++ b/app/Utils/Workerman/WsConnection.php @@ -0,0 +1,1313 @@ + [ + 'market_kline' => 'market.$symbol.kline.$period', + 'market_detail' => 'market.$symbol.detail', + 'market_depth' => 'market.$symbol.depth.$type', + 'market_trade' => 'market.$symbol.trade.detail', //成交的交易 + // 'market_ticker'=>'market.$symbol.ticker',//最新价跳动 + ], + ]; + + public function __construct($worker_id) + { + $this->worker_id = $worker_id; + AsyncTcpConnection::$defaultMaxPackageSize = 1048576000; + } + + public function getConnection() + { + return $this->connection; + } + + /** + * 绑定所有事件到连接 + * + * @return void + */ + protected function bindEvent() + { + foreach ($this->events as $key => $event) { + if (method_exists($this, $event)) { + $this->connection && $this->connection->$event = [$this, $event]; + //echo '绑定' . $event . '事件成功' . PHP_EOL; + } + } + } + + /** + * 解除连接所有绑定事件 + * + * @return void + */ + protected function unBindEvent() + { + foreach ($this->events as $key => $event) { + if (method_exists($this, $event)) { + $this->connection && $this->connection->$event = null; + //echo '解绑' . $event . '事件成功' . PHP_EOL; + } + } + } + + public function getSubscribed($topic = null) + { + if (is_null($topic)) { + return $this->subscribed; + } + return $this->subscribed[$topic] ?? null; + } + + protected function setSubscribed($topic, $value) + { + $this->subscribed[$topic] = $value; + } + + protected function delSubscribed($topic) + { + unset($this->subscribed[$topic]); + } + + public function connect() + { + $this->connection = new AsyncTcpConnection($this->server_address); + $this->bindEvent(); + $this->connection->transport = 'ssl'; + $this->connection->connect(); + } + + public function onConnect($con) + { + //连接成功后定期发送ping数据包检测服务器是否在线 + $this->timer = Timer::add($this->server_ping_freq, [$this, 'ping'], [$this->connection], true); + if ($this->worker_id < 8) { + $this->sendKlineTimer = Timer::add($this->send_freq, [$this, 'writeMarketKline'], [], true); + } else { + $this->depthTimer = Timer::add($this->send_freq, [$this, 'sendDepthData'], [], true); + $this->sendMatchTradeTimer = Timer::add($this->send_freq, [$this, 'sendMatchTradeData'], [], true); + } + + if ($this->worker_id == 5) { + $this->handleTimer = Timer::add($this->send_freq, [self::class, 'sendLeverHandle'], [], true); + } + + if ($this->worker_id == 0) { + $this->microTradeHandleTimer = Timer::add($this->micro_trade_freq, [self::class, 'handleMicroTrade'], [], true); + } + //添加订阅事件代码 + $this->subscribe($con); + } + + public function onClose($con) + { + echo $this->server_address . '连接关闭' . PHP_EOL; + $path = base_path() . '/storage/logs/wss/'; + $filename = date('Ymd') . '.log'; + file_exists($path) || @mkdir($path); + error_log(date('Y-m-d H:i:s') . ' ' . $this->server_address . '连接关闭' . PHP_EOL, 3, $path . $filename); + //解除事件 + $this->timer && Timer::del($this->timer); + $this->sendKlineTimer && Timer::del($this->sendKlineTimer); + $this->pingTimer && Timer::del($this->pingTimer); + $this->depthTimer && Timer::del($this->depthTimer); + $this->handleTimer && Timer::del($this->handleTimer); + $this->microTradeHandleTimer && Timer::del($this->microTradeHandleTimer); + $this->unBindEvent(); + unset($this->connection); + $this->connection = null; + $this->subscribed = null; //清空订阅 + echo '尝试重新连接' . PHP_EOL; + $this->connect(); + } + + public function close($msg) + { + $path = base_path() . '/storage/logs/wss/'; + $filename = date('Ymd') . '.log'; + file_exists($path) || @mkdir($path); + error_log(date('Y-m-d H:i:s') . ' ' . $msg, 3, $path . $filename); + $this->connection->destroy(); + } + + protected function makeSubscribeTopic($topic_template, $param) + { + $need_param = []; + $match_count = preg_match_all('/\$([a-zA-Z_]\w*)/', $topic_template, $need_param); + if ($match_count > 0 && count(reset($need_param)) > count($param)) { + throw new \Exception('所需参数不匹配'); + } + $diff = array_diff(next($need_param), array_keys($param)); + if (count($diff) > 0) { + throw new \Exception('topic:' . $topic_template . '缺少参数:' . implode(',', $diff)); + } + return preg_replace_callback('/\$([a-zA-Z_]\w*)/', function ($matches) use ($param) { + extract($param); + $value = $matches[1]; + return $$value ?? ''; + }, $topic_template); + } + + public function onBufferFull() + { + echo 'buffer is full' . PHP_EOL; + } + + protected function subscribe($con) + { + $periods = ['1min', '5min', '15min', '30min', '60min', '1day', '1mon', '1week']; //['1day', '1min']; + if ($this->worker_id < 8) { + $value = $periods[$this->worker_id]; + echo '进程'. $this->worker_id . '开始订阅' . $value . '数据' . PHP_EOL; + $this->subscribeKline($con, $value); //订阅k线行情 + } else { + if ($this->worker_id == 8) { + $this->subscribeMarketDepth($con); //订阅盘口数据 + $this->subscribeMarketTrade($con); //订阅全站交易数据 + } + } + } + + //订阅回调 + protected function onSubscribe($data) + { + if ($data->status == 'ok') { + echo $data->subbed . '订阅成功' . PHP_EOL; + } else { + echo '订阅失败:' . $data->{'err-msg'} . PHP_EOL; + } + } + /** + * 订阅全站交易(已完成) + * @param \Workerman\Connection\ConnectionInterface $con + * @param \App\Models\CurrencyMatch $currency_match + * @return void + */ + public function subscribeMarketTrade($con) + { + $currency_list = CurrencyMatch::getHuobiMatchs(); + foreach ($currency_list as $key => $currency_match) { + $param = [ + 'symbol' => $currency_match->match_name, + ]; + $topic = $this->makeSubscribeTopic($this->topicTemplate['sub']['market_trade'], $param); + $sub_data = json_encode([ + 'sub' => $topic, + 'id' => $topic, + ]); + $subscribed_data = $this->getSubscribed($topic); + $match_data = $subscribed_data['match'] ?? []; + $match_data[] = $currency_match; + $this->setSubscribed($topic, [ + 'callback' => 'onMatchTrade', + 'match' => $match_data, + ]); + // 未订阅过的才能订阅 + if (is_null($subscribed_data)) { + $con->send($sub_data); + } + } + } + + //订阅K线行情 + protected function subscribeKline($con, $period) + { + $currency_match = CurrencyMatch::getHuobiMatchs(); + foreach ($currency_match as $key => $value) { + $param = [ + 'symbol' => $value->match_name, + 'period' => $period, + ]; + $topic = $this->makeSubscribeTopic($this->topicTemplate['sub']['market_kline'], $param); + $sub_data = json_encode([ + 'sub' => $topic, + 'id' => $topic, + //'freq-ms' => 5000, //推送频率,实测只能是0和5000,与官网文档不符 + ]); + //未订阅过的才能订阅 + if (is_null($this->getSubscribed($topic))) { + $this->setSubscribed($topic, [ + 'callback' => 'onMarketKline', + 'match' => $value + ]); + $con->send($sub_data); + } + } + } + + protected function onMarketKline($con, $data, $match) + { + + + + + $topic = $data->ch; + $msg = date('Y-m-d H:i:s') . ' 进程' . $this->worker_id . '接收' . $topic . '行情' . PHP_EOL; + list($name, $symbol, $detail_name, $period) = explode('.', $topic); + $subscribed_data = $this->getSubscribed($topic); + $currency_match = $subscribed_data['match']; + $key = $currency_match->currency_name . '.' . $currency_match->legal_name; + $tick = $data->tick; + + + + + $market_data = [ + 'id' => $tick->id, + 'period' => $period, + 'base-currency' => $currency_match->currency_name, + 'quote-currency' => $currency_match->legal_name, + 'open' => sctonum($tick->open), + 'close' => sctonum($tick->close), + 'high' => sctonum($tick->high), + 'low' => sctonum($tick->low), + 'vol' => sctonum($tick->vol), + 'amount' => sctonum($tick->amount), + ]; + + $kline_data = [ + 'type' => 'kline', + 'period' => $period, + 'match_id' => $currency_match->id, + 'currency_id' => $currency_match->currency_id, + 'currency_name' => $currency_match->currency_name, + 'legal_id' => $currency_match->legal_id, + 'legal_name' => $currency_match->legal_name, + 'open' => sctonum($tick->open), + 'close' => sctonum($tick->close),//实时价格 + 'high' => sctonum($tick->high), + 'low' => sctonum($tick->low), + 'symbol' => $currency_match->currency_name . '/' . $currency_match->legal_name, + 'volume' => sctonum($tick->amount), + 'time' => $tick->id * 1000, + ]; + + + $m_gp = CurrencyMatch::forward_gp(); + + $gp_data = [ + 'type' => 'kline', + 'period' => '1min', + 'match_id' => $m_gp['match_id'], + 'currency_id' => $m_gp['currency_id'], + 'currency_name' => $m_gp['name'], + 'legal_id' => 3, + 'legal_name' => 'USDC', + 'open' => $m_gp['open'], + 'close' => $m_gp['close'],//实时价格 + 'high' => $m_gp['high'], + 'low' => $m_gp['low'], + 'symbol' => $m_gp['name'] . '/' . 'USDC', + 'volume' => $m_gp['volume'], + 'time' => time().'000', + ]; + + + + + if($period=='30min'){ + $kline_data = $gp_data; + $key = $m_gp['name'].'.USDC'; + + + } + + + $m_etf = CurrencyMatch::forward_etf(); + $etf_data = [ + 'type' => 'kline', + 'period' => '1min', + 'match_id' => $m_etf['match_id'], + 'currency_id' => $m_etf['currency_id'], + 'currency_name' => $m_etf['name'], + 'legal_id' => 3, + 'legal_name' => 'USDC', + 'open' => $m_etf['open'], + 'close' => $m_etf['close'],//实时价格 + 'high' => $m_etf['high'], + 'low' => $m_etf['low'], + 'symbol' => $m_etf['name'] . '/' . 'USDC', + 'volume' => $m_etf['volume'], + 'time' => time().'000', + ]; + + if($period=='60min'){ + $kline_data = $etf_data; + $key = $m_etf['name'].'.USDC'; + + + + + } + + + + + + + + $forward_sj = CurrencyMatch::forward_sj(); + $forward_data = [ + 'type' => 'kline', + 'period' => '1min', + 'match_id' => $forward_sj['match_id'], + 'currency_id' => $forward_sj['currency_id'], + 'currency_name' => $forward_sj['name'], + 'legal_id' => 3, + 'legal_name' => 'USDC', + 'open' => $forward_sj['open'], + 'close' => $forward_sj['close'],//实时价格 + 'high' => $forward_sj['high'], + 'low' => $forward_sj['low'], + 'symbol' => $forward_sj['name'] . '/' . 'USDC', + 'volume' => $forward_sj['volume'], + 'time' => time().'000', + ]; + + + + + if($period=='1week'){ + $kline_data = $forward_data; + $key = $forward_sj['name'].'.USDC'; + + + } + + + $foreign_sj = CurrencyMatch::foreign_sj(); + $foreign_data = [ + 'type' => 'kline', + //'period' => '1dy', + 'period' => '1min', + 'match_id' => $foreign_sj['match_id'], + 'currency_id' => $foreign_sj['currency_id'], + 'currency_name' => $foreign_sj['name'], + 'legal_id' => 3, + 'legal_name' => 'USDC', + 'open' => $foreign_sj['open'], + 'close' => $foreign_sj['close'],//实时价格 + 'high' => $foreign_sj['high'], + 'low' => $foreign_sj['low'], + 'symbol' => $foreign_sj['name'] . '/' . 'USDC', + 'volume' => $foreign_sj['volume'], + 'time' => time().'000', + ]; + if($period=='1mon'){ + $kline_data = $foreign_data; + $key = $foreign_sj['name'].'.USDC'; + + } + + //EsearchMarket::dispatch($market_data)->onQueue('esearch:market:' . $period); + // $key = $currency_match->currency_name . '.' . $currency_match->legal_name; + + + self::$marketKlineData[$period][$key] = [ + 'market_data' => $market_data, + 'kline_data' => $kline_data, + 'forward_data' => $forward_data, + 'foreign_data' => $foreign_data, + 'gp_data' => $gp_data, + 'etf_data' => $etf_data, + ]; + + + + $rand = rand(1,4); + + + if($period=='60min'&&$rand==2){ + //推送币种的日行情(带涨副) + $change = $this->calcIncreasePair($etf_data); + bc_comp($change, 0) > 0 && $change = '+' . $change; + //追加涨副等信息 + $daymarket_data = [ + 'type' => 'daymarket', + 'period' => '1dy', //1dy + 'change' => $change, + 'now_price' => $etf_data['close'], + 'api_form' => 'alicloudapi', + ]; + + + + $kline_data = array_merge($etf_data, $daymarket_data); + + + self::$marketKlineData[$period][$key]['kline_data'] = $kline_data; + + + } + + + if($period=='30min'&&$rand==2){ + //推送币种的日行情(带涨副) + $change = $this->calcIncreasePair($gp_data); + bc_comp($change, 0) > 0 && $change = '+' . $change; + //追加涨副等信息 + $daymarket_data = [ + 'type' => 'daymarket', + 'period' => '1dy', //1dy + 'change' => $change, + 'now_price' => $gp_data['close'], + 'api_form' => 'alicloudapi', + ]; + + + + $kline_data = array_merge($gp_data, $daymarket_data); + + + self::$marketKlineData[$period][$key]['kline_data'] = $kline_data; + + + } + + + if($period=='1week'&&$rand==2){ + //推送币种的日行情(带涨副) + $change = $this->calcIncreasePair($forward_data); + bc_comp($change, 0) > 0 && $change = '+' . $change; + //追加涨副等信息 + $daymarket_data = [ + 'type' => 'daymarket', + 'period' => '1dy', //1dy + 'change' => $change, + 'now_price' => $forward_data['close'], + 'api_form' => 'sina_api', + ]; + + + + $kline_data = array_merge($forward_data, $daymarket_data); + + + self::$marketKlineData[$period][$key]['kline_data'] = $kline_data; + + + } + + + if($period=='1mon'&&$rand==2){ + //推送币种的日行情(带涨副) + $change = $this->calcIncreasePair($foreign_data); + bc_comp($change, 0) > 0 && $change = '+' . $change; + //追加涨副等信息 + $daymarket_data = [ + 'type' => 'daymarket', + 'period' => '1dy', //1dy + 'change' => $change, + 'now_price' => $foreign_data['close'], + 'api_form' => 'sina_api', + ]; + + + + $kline_data = array_merge($foreign_data, $daymarket_data); + + + self::$marketKlineData[$period][$key]['kline_data'] = $kline_data; + + + } + + + + if ($period == '1day') { + //推送币种的日行情(带涨副) + $change = $this->calcIncreasePair($kline_data); + bc_comp($change, 0) > 0 && $change = '+' . $change; + //追加涨副等信息 + $daymarket_data = [ + 'type' => 'daymarket', + 'change' => $change, + 'now_price' => $market_data['close'], + 'api_form' => 'huobi_websocket', + ]; + + + $kline_data = array_merge($kline_data, $daymarket_data); + + $currencyInfo=DB::table('currency')->where('name',$currency_match->currency_name)->first(); + if($currencyInfo->enabled==1){ + + $das=DB::table('currency_contact')->where('currency_id',$currencyInfo->id)->where('time',date('YmdHi',time()))->first(); + if($currencyInfo->yujicontact !=$currencyInfo->min_unit && !$das){ + $sis=bcmul($kline_data['open'],$currencyInfo->count/$currencyInfo->min_unit/100,4); + $yujicontact=$currencyInfo->yujicontact + 1; + }else{ + $sis=0; + $yujicontact=$currencyInfo->yujicontact; + } + + $oncontact=bcadd($currencyInfo->oncontact,$sis,4); + + + DB::table('currency')->where(['name' => $currency_match->currency_name])->update(['oncontact'=>$oncontact,'yujicontact'=>$yujicontact]); + + $rsd=[ + 'currency_id'=>$currencyInfo->id, + 'time'=>date('YmdHi',time()), + 'oncontact'=>$oncontact + ]; + if(!$das){ + DB::table('currency_contact')->insert($rsd); + } + + } + + $sisValue =$currencyInfo->oncontact; + + self::$marketKlineData[$period][$key]['kline_data'] = $kline_data; + //SendMarket::dispatch($kline_data)->onQueue('kline.1day'); + /* + //存入数据库 + CurrencyQuotation::getInstance($currency_match->legal_id, $currency_match->currency_id) + ->updateData([ + 'change' => $change, + 'now_price' => $tick->close, + 'volume' => $tick->amount, + ]); + */ + } /*elseif ($period == '5min') { + echo str_repeat('*', 80) . PHP_EOL; + dump($kline_data); + echo str_repeat('*', 80) . PHP_EOL; + }*/ + // file_put_contents('/www/wwwroot/crypto/public/d6.txt',$base_currency."---".$peroid."---".json_encode($result).PHP_EOL,FILE_APPEND); + + + //加载配置文件 tasks_matches + $tasks_matches=getConfig("config/tasks_matches.php"); + $sys_matches=$tasks_matches["tasks_matches"];//获取到“交易所”的交易对 + foreach ($sys_matches as $k=>$v){ + $self_match_key = $v['name'] . '.' . $v["legal_name"]; + + + $to = time(); + + $t= DB::table('myquotation')->where('itime','<=', $to)->where('period','1min')->orderby('id', 'desc')->first(); + if(!empty($t)) { + + $f1 = "config/kline/".$t->itime."_kline_1min_".$v["name"].".php"; + $f2 = "config/kline/".$t->itime."_daymarket_".$v["name"].".php"; + + + if(!file_exists('/www/wwwroot/crypto/'.$f1)){ + + $f1 = "config/kline_1min_".strtolower($v["name"]).".php"; + } + + if(!file_exists('/www/wwwroot/crypto/'.$f2)){ + + $f2 = "config/daymarket_".strtolower($v["name"]).".php"; + } + + }else{ + + $f1 = "config/kline_1min_".strtolower($v["name"]).".php"; + $f2 = "config/daymarket_".strtolower($v["name"]).".php"; + } + + + + // file_put_contents('/www/wwwroot/crypto/public/t1.txt',$f1.PHP_EOL,FILE_APPEND); + + + // $f1 = "config/kline_1min_".strtolower($v["name"]).".php"; + // $f2 = "config/daymarket_".strtolower($v["name"]).".php"; + + $adt=getConfig($f1); + UserChat::sendChat($adt["libra_data"]); + // UserChat::sendChat($adt["libra_data"]); + $adt2=getConfig($f2); + UserChat::sendChat($adt2["libra_data"]); + + $biname=$v["name"]; + $biname2=strtolower($biname); + $rkey = "market.{$biname2}usdt.kline.1min"; + $adt=$adt["libra_data"]; + Redis::set($rkey, json_encode(['ch' => $rkey, 'ts' => $adt["time"], 'tick' => [ + 'id' => $adt["time"]/1000, + 'open' => $adt["open"], + 'close' => $adt["close"], + 'low' => $adt["low"], + 'high' => $adt["high"], + 'vol' => $adt["volume"], + 'amount' => $adt["volume"], + 'count' => rand(10, 120) + ]])); + $obj = json_decode(Redis::get($rkey)); + if (!$obj) { + return; //必须 有这个obj才行的 + } + $price=$adt["now_price"]; + + + //通知行情 + $market_data_new =$adt; + $kline_data_new = $adt2["libra_data"]; + + $self_market_data = [ + 'id' => $adt["time"]/1000, + 'period' => '1min', + 'base-currency' => $adt["currency_name"], + 'quote-currency' => $v["legal_name"], + 'open' => sctonum($adt["open"]), + 'close' => sctonum($adt["close"]), + 'high' => sctonum($adt["high"]), + 'low' => sctonum($adt["low"]), + 'vol' => sctonum($adt["volume"]), + 'amount' => sctonum($adt["close"]) + ]; + + $self_kline_data = [ + 'type' => 'kline', + 'period' => "1min", + 'match_id' => $v["id"], + 'currency_id' => $kline_data_new["currency_id"], + 'currency_name' => $kline_data_new["currency_name"], + 'legal_id' => $kline_data_new["legal_id"], + 'legal_name' => $kline_data_new["legal_name"], + 'open' => sctonum($kline_data_new["open"]), + 'close' => sctonum($kline_data_new["close"]), + 'high' => sctonum($kline_data_new["high"]), + 'low' => sctonum($kline_data_new["low"]), + 'symbol' => $kline_data_new["symbol"], + 'volume' => $kline_data_new["volume"], + 'time' => $kline_data_new["time"] + ]; + + $daymarket_data = [ + 'type' => 'daymarket', + 'period' => '1min', //1dy + 'change' => sctonum($adt2["libra_data"]['change'],2), + 'now_price' => sctonum($kline_data_new["close"],4), + 'api_form' => 'sina_api', + ]; + + //file_put_contents('/www/wwwroot/crypto/public/t.txt',json_encode($daymarket_data).PHP_EOL,FILE_APPEND); + + $self_kline_data = array_merge($self_kline_data, $daymarket_data); + + + // self::$marketKlineData[$period][$key]['kline_data'] = $kline_data; + + + self::$marketKlineData["1min"][$self_match_key] = ['market_data' => $self_market_data, 'kline_data' => $self_kline_data, + 'forward_data' => $forward_data, + 'foreign_data' => $foreign_data, + 'gp_data' => $gp_data, + 'etf_data' => $etf_data, + ]; + $self_data[] = [ + 'id' => time() . rand(1, 100000), + 'amount' => rand(100, 39 * 56 - 184) / (16 * 56 + 104), + 'direction' => "buy", + 'price' => $price + rand(0, 9) * 0.00001, rand(50, 300), + 'tradeId' => time() . rand(1, 3333), + 'ts' => self::getMillisecond() + ]; + $self_data[] = [ + 'id' => time() . rand(1, 100000), + 'amount' => rand(100, 39 * 56 - 184) / (16 * 56 + 104), + 'direction' => "sell", + 'price' => $price + rand(0, 9) * 0.00001, rand(50, 300), + 'tradeId' => time() . rand(1, 3333), + 'ts' => self::getMillisecond() + ]; + $self_trade_data = [ + 'type' => 'match_trade', + 'symbol' => $kline_data_new["currency_name"] . '/' . $kline_data_new["legal_name"], + 'base-currency' => $kline_data_new["currency_name"], + 'quote-currency' => $kline_data_new["legal_name"], + 'currency_id' => $kline_data_new["currency_id"], + 'currency_name' => $kline_data_new["currency_name"], + 'legal_id' => $kline_data_new["legal_id"], + 'legal_name' => $kline_data_new["legal_name"], + 'data' => $self_data + ]; + self::$matchTradeData[$kline_data_new["currency_name"] . '.' . $kline_data_new["legal_name"]] = $self_trade_data; + + self::sendMatchTradeData(); + + CurrencyQuotation::getInstance($adt2["libra_data"]['legal_id'], $adt2["libra_data"]['currency_id']) + ->updateData([ + 'change' => sctonum($adt2["libra_data"]['change'],2), + 'now_price' => $adt2["libra_data"]['close'], + 'volume' => $adt2["libra_data"]['volume'], + ]); + } + + + + + + + + } + + //订阅盘口数据 + protected function subscribeMarketDepth($con) + { + $currency_match = CurrencyMatch::getHuobiMatchs(); + foreach ($currency_match as $key => $value) { + $param = [ + 'symbol' => $value->match_name, + 'type' => 'step0', + ]; + $topic = $this->makeSubscribeTopic($this->topicTemplate['sub']['market_depth'], $param); + $sub_data = json_encode([ + 'sub' => $topic, + 'id' => $topic, + ]); + //未订阅过的才能订阅 + if (is_null($this->getSubscribed($topic))) { + $this->setSubscribed($topic, [ + 'callback' => 'onMarketDepth', + 'match' => $value + ]); + $con->send($sub_data); + } + } + } + + /** + * 撮合交易全站交易数据回调 + * @param \Workerman\Connection\ConnectionInterface $con + * @param array $data + * @param \Illuminate\Database\Eloquent\Collection $currency_matches + * @return void + */ + protected function onMatchTrade($con, $data, $currency_matches) + { + $topic = $data->ch; + $data = $data->tick->data; + foreach ($currency_matches as $key => $currency_match) { + $symbol_key = $currency_match->currency_name . '.' . $currency_match->legal_name; + $trade_data = [ + 'type' => 'match_trade', + 'symbol' => $currency_match->currency_name . '/' . $currency_match->legal_name, + 'base-currency' => $currency_match->currency_name, + 'quote-currency' => $currency_match->legal_name, + 'currency_id' => $currency_match->currency_id, + 'currency_name' => $currency_match->currency_name, + 'legal_id' => $currency_match->legal_id, + 'legal_name' => $currency_match->legal_name, + 'data' => $data, + ]; + self::$matchTradeData[$symbol_key] = $trade_data; + } + } + + // protected function onMarketDepth($con, $data, $currency_matches) + // { + // try { + // $topic = $data->ch; + // $limit = 10; + // $tick = $data->tick; + // $bids = array_slice($tick->bids, 0, $limit); + // $asks = array_slice($tick->asks, 0, $limit); + // krsort($asks); + // $asks = array_values($asks); + // // 将模拟克隆的交易对也添加上数据 + // foreach ($currency_matches as $key => $currency_match) { + // $depth_data = [ + // 'type' => 'market_depth', + // 'symbol' => $currency_match->currency_name . '/' . $currency_match->legal_name, + // 'base-currency' => $currency_match->currency_name, + // 'quote-currency' => $currency_match->legal_name, + // 'currency_id' => $currency_match->currency_id, + // 'currency_name' => $currency_match->currency_name, + // 'legal_id' => $currency_match->legal_id, + // 'legal_name' => $currency_match->legal_name, + // 'bids' => $bids, //买入盘口 + // 'asks' => $asks, //卖出盘口 + // ]; + // $symbol_key = $currency_match->currency_name . '.' . $currency_match->legal_name; + // self::$marketDepthData[$symbol_key] = $depth_data; + // } + // } catch (\Throwable $th) { + + // } + // } + + + //盘口数据回调 + protected function onMarketDepth($con, $data, $match) + { + $topic = $data->ch; + $subscribed_data = $this->getSubscribed($topic); + $currency_match = $subscribed_data['match']; + krsort($data->tick->asks); + $data->tick->asks = array_values($data->tick->asks); + + $rand = rand(1,5); + if($rand==1){//期货 + $info = CurrencyMatch::forward_sj(); + $price=$info['close']; + }else if($rand==2){ + $info = CurrencyMatch::foreign_sj(); + // $info = CurrencyMatch::forward_sj();//临时 + $price=$info['close']; + }else if($rand==3){ + $info = CurrencyMatch::forward_gp(); + // $info = CurrencyMatch::forward_sj();//临时 + $price=$info['close']; + }else if($rand==4){ + $info = CurrencyMatch::forward_etf(); + // $info = CurrencyMatch::forward_sj();//临时 + $price=$info['close']; + } + + if($rand==1||$rand==2||$rand==3||$rand==4){//期货 或外汇 + + /* $array = array(1,1,1,1,1,1,1,1,1,1); + foreach ($array as $k=>$v){ + $bids[$k][0] = rand(1,2)==1?$info['close']+$info['close']/rand(2,6):$info['close']-$info['close']/rand(30,50); + $bids[$k][1] = '0.'.rand(0,10); + } + foreach ($array as $k=>$v){ + $asks[$k][0] = rand(1,2)==1?$info['close']+$info['close']/rand(2,6):$info['close']-$info['close']/rand(30,50); + $asks[$k][1] = '0.'.rand(0,10); + } + + */ + for ($i = 0; $i < 10; $i++) { + $bids[] = [$price + rand(0, 2) * 0.00001, rand(50, 300)]; + } + for ($i = 0; $i < 10; $i++) { + $asks[] = [$price - rand(0, 2) * 0.00001, rand(50, 300)]; + } + + $depth_data = [ + 'type' => 'market_depth', + 'symbol' => $info['name'] . '/' . 'USDC', + 'base-currency' => $info['name'],//币名称 + 'quote-currency' => 'USDC',//换汇名称 + 'currency_id' => $info['currency_id'],//币id + 'currency_name' => $info['name'],//币名称 + 'legal_id' => 3, + 'legal_name' => 'USDC', + 'bids' => $bids, //买入盘口 + 'asks' => $asks, //卖出盘口 + ]; + + }else if($rand==5){//元数据 + $depth_data = [ + 'type' => 'market_depth', + 'symbol' => $currency_match->currency_name . '/' . $currency_match->legal_name, + 'base-currency' => $currency_match->currency_name, + 'quote-currency' => $currency_match->legal_name, + 'currency_id' => $currency_match->currency_id, + 'currency_name' => $currency_match->currency_name, + 'legal_id' => $currency_match->legal_id, + 'legal_name' => $currency_match->legal_name, + 'bids' => array_slice($data->tick->bids, 0, 10), //买入盘口 + 'asks' => array_slice($data->tick->asks, 0, 10), //卖出盘口 + ]; + } + + + + + + + $symbol_key = $currency_match->currency_name . '.' . $currency_match->legal_name; + self::$marketDepthData[$symbol_key] = $depth_data; + } + + + + + + //盘口数据回调 + protected function onMarketDepth1111($con, $data, $match) + { + $topic = $data->ch; + $subscribed_data = $this->getSubscribed($topic); + $currency_match = $subscribed_data['match']; + krsort($data->tick->asks); + $data->tick->asks = array_values($data->tick->asks); + + $rand = rand(1,3); + if($rand==1){//期货 + $info = CurrencyMatch::forward_sj(); + }else if($rand==2){ + $info = CurrencyMatch::foreign_sj(); + } + + if($rand==1||$rand==2){//期货 或外汇 + + $array = array(1,1,1,1,1,1,1,1,1,1); + foreach ($array as $k=>$v){ + $bids[$k][0] = rand(1,2)==1?$info['close']+$info['close']/rand(2,6):$info['close']-$info['close']/rand(30,50); + $bids[$k][1] = '0.'.rand(0,10); + } + foreach ($array as $k=>$v){ + $asks[$k][0] = rand(1,2)==1?$info['close']+$info['close']/rand(2,6):$info['close']-$info['close']/rand(30,50); + $asks[$k][1] = '0.'.rand(0,10); + } + + $depth_data = [ + 'type' => 'market_depth', + 'symbol' => $info['name'] . '/' . 'USDC', + 'base-currency' => $info['name'],//币名称 + 'quote-currency' => 'USDC',//换汇名称 + 'currency_id' => $info['currency_id'],//币id + 'currency_name' => $info['name'],//币名称 + 'legal_id' => 3, + 'legal_name' => 'USDC', + 'bids' => $bids, //买入盘口 + 'asks' => $asks, //卖出盘口 + ]; + + }else if($rand==3){//元数据 + $depth_data = [ + 'type' => 'market_depth', + 'symbol' => $currency_match->currency_name . '/' . $currency_match->legal_name, + 'base-currency' => $currency_match->currency_name, + 'quote-currency' => $currency_match->legal_name, + 'currency_id' => $currency_match->currency_id, + 'currency_name' => $currency_match->currency_name, + 'legal_id' => $currency_match->legal_id, + 'legal_name' => $currency_match->legal_name, + 'bids' => array_slice($data->tick->bids, 0, 10), //买入盘口 + 'asks' => array_slice($data->tick->asks, 0, 10), //卖出盘口 + ]; + } + + + + + + + $symbol_key = $currency_match->currency_name . '.' . $currency_match->legal_name; + self::$marketDepthData[$symbol_key] = $depth_data; + } + + /** + * 发送盘口数据 + * + * @return void + */ + + + public function sendDepthData() + { + $market_depth = self::$marketDepthData; + foreach ($market_depth as $depth_data) { + SendMarket::dispatch($depth_data)->onQueue('market.depth'); + } + } + + //取消订阅 + protected function unsubscribe() + { + } + + protected function onUnsubscribe() + { + } + + public function onMessage($con, $data) + { + $data = gzdecode($data); + $data = json_decode($data, false, 512, JSON_BIGINT_AS_STRING); + + if (isset($data->ping)) { + $this->onPong($con, $data); + } elseif (isset($data->pong)) { + $this->onPing($con, $data); + } elseif (isset($data->id) && $this->getSubscribed($data->id) != null) { + $this->onSubscribe($data); + } elseif (isset($data->id)) { + + } else { + $this->onData($con, $data); + } + } + + protected function onData($con, $data) + { + if (isset($data->ch)) { + $subscribed = $this->getSubscribed($data->ch); + if ($subscribed != null) { + //调用回调处理 + $callback = $subscribed['callback']; + $this->$callback($con, $data, $subscribed['match']); + } else { + //不在订阅中的数据 + } + } else { + echo '未知数据' . PHP_EOL; + var_dump($data); + } + } + + /** + * 发送全站交易数据 + * + * @return void + */ + public function sendMatchTradeData() + { + $market_trade = self::$matchTradeData; + foreach ($market_trade as $trade_data) { + SendMarket::dispatch($trade_data)->onQueue('send:match:trade'); + } + self::$matchTradeData = []; //发送完清空,以避免重复发送相同的数据 + } + + + public static function sendLeverHandle() + { +// echo date('Y-m-d H:i:s') . '定时器取价格' . PHP_EOL; + $now = microtime(true); +// $master_start = microtime(true); +// echo str_repeat('=', 80) . PHP_EOL; +// echo date('Y-m-d H:i:s') . '开始发送价格到杠杆交易系统' . PHP_EOL; +// echo '{' . PHP_EOL; + $market_kiline = self::$marketKlineData['1day']; + foreach ($market_kiline as $key => $value) { + $kline_data = $value['kline_data']; + $start = microtime(true); +// echo "\t" . date('Y-m-d H:i:s') . ' 发送' . $key . ',价格:' . $kline_data['close'] . PHP_EOL; + $params = [ + 'legal_id' => $kline_data['legal_id'], + 'legal_name' => $kline_data['legal_name'], + 'currency_id' => $kline_data['currency_id'], + 'currency_name' => $kline_data['currency_name'], + 'now_price' => $kline_data['close'], + 'now' => $now + ]; + //价格大于0才进行任务推送 + if (bc_comp($kline_data['close'], 0) > 0) { + LeverUpdate::dispatch($params)->onQueue('lever:update'); + CoinTradeHandel::dispatch($params)->onQueue('coin:trade'); +// LeverPushPrice::dispatch($params)->onQueue('lever:push:price'); + } + $end = microtime(true); +// echo "\t" . date('Y-m-d H:i:s') . $key . '处理完成,耗时' .($end - $start) . '秒' . PHP_EOL; + } +// $master_end = microtime(true); +// echo '}' . PHP_EOL; +// echo date('Y-m-d H:i:s') . '杠杆交易系统处理完成,耗时' . ($master_end - $master_start) . '秒' . PHP_EOL; +// echo str_repeat('=', 80) . PHP_EOL; + } + + public static function handleMicroTrade() + { + //self::$marketKlineData[$period][$key]['kline_data'] = $kline_data; + $market_data = self::$marketKlineData; + foreach ($market_data as $period => $data) { + foreach ($data as $key => $symbol) { + echo '秒合约时间:' . time() . ', Symbol:' . $key . '.' . $period . '数据' . PHP_EOL; + if ($period == '1min') { + //处理秒合约 + // $match_id=$symbol['kline_data']['match_id']; + // $c_m=CurrencyMatch::find($match_id); + // if($c_m->open_microtrade == 1){ + HandleMicroTrade::dispatch($symbol['kline_data'])->onQueue('micro_trade:handle'); + HandleMicroTrade::dispatch($symbol['forward_data'])->onQueue('micro_trade:handle');//88888888 + HandleMicroTrade::dispatch($symbol['foreign_data'])->onQueue('micro_trade:handle'); + HandleMicroTrade::dispatch($symbol['gp_data'])->onQueue('micro_trade:handle'); + HandleMicroTrade::dispatch($symbol['etf_data'])->onQueue('micro_trade:handle'); + // } + + } else { + continue; + } + } + } + } + + public function writeMarketKline() + { + if ($this->worker_id < 8) { + $market_data = self::$marketKlineData; + foreach ($market_data as $period => $data) { + foreach ($data as $key => $symbol) { + echo '处理' . $key . '.' . $period . '数据' . PHP_EOL; + // file_put_contents('/www/wwwroot/crypto/public/d5.txt',$key . '-----' . $period ."---".json_encode($symbol).PHP_EOL,FILE_APPEND); + $result = MarketHour::getEsearchMarketById( + $symbol['kline_data']['currency_name'], + $symbol['market_data']['quote-currency'], + $period, + // $symbol['kline_data']['period'], + $symbol['market_data']['id'] + ); + // if (isset($result['_source'])) { + // $origin_data = $result['_source']; + + $number = array($symbol['kline_data']['high'],$symbol['kline_data']['low'],$symbol['kline_data']['close'],$symbol['kline_data']['open']); + + + $symbol['kline_data']['high'] =round(max($number),8); + $symbol['kline_data']['low'] =round(min($number),8); + + $symbol['market_data']['high'] =round(max($number),8); + $symbol['market_data']['low'] =round(min($number),8); + // bc_comp($symbol['kline_data']['high'], $origin_data['high']) < 0 + // && $symbol['kline_data']['high'] = $origin_data['high']; //新过来的价格如果不高于原最高价则不更新 + // bc_comp($symbol['kline_data']['low'], $origin_data['low']) > 0 + // && $symbol['kline_data']['low'] = $origin_data['low']; //新过来的价格如果不低于原最低价则不更新 + // } + + + $currencyInfo=DB::table('currency')->where('name',$symbol['market_data']['base-currency'])->first(); + if($currencyInfo){ + $sisValue =$currencyInfo->oncontact; + if($sisValue!=0){ + $symbol['kline_data']['high'] = round($symbol['kline_data']['high'] + $sisValue,8); + $symbol['kline_data']['close'] = round($symbol['kline_data']['close'] + $sisValue,8); + $symbol['kline_data']['low'] = round($symbol['kline_data']['low'] + $sisValue,8); + $symbol['market_data']['high'] = round($symbol['market_data']['high'] + $sisValue,8); + $symbol['market_data']['close'] = round($symbol['market_data']['close'] + $sisValue,8); + $symbol['market_data']['low'] = round($symbol['market_data']['low'] + $sisValue,8); + if($period == '1day'){ + $symbol['kline_data']['change'] = ($symbol['kline_data']['close'] - $symbol['kline_data']['open'])/$symbol['kline_data']['open']*100; + $symbol['kline_data']['change'] = round($symbol['kline_data']['change'],4); + } + + + // file_put_contents('/www/wwwroot/crypto/public/s.txt',json_encode($symbol).PHP_EOL,FILE_APPEND); + } + } + + + SendMarket::dispatch($symbol['kline_data'])->onQueue('kline.all'); + // EsearchMarket::dispatch($symbol['market_data'])->onQueue('esearch:market');//统一用一个队列 + if ($period == '1min') { + // var_dump($symbol['kline_data']); + //推送一分钟行情 + //SendMarket::dispatch($symbol['kline_data'])->onQueue('kline.1min'); + //更新币种价格 + UpdateCurrencyPrice::dispatch($symbol['kline_data'])->onQueue('update_currency_price'); + } elseif ($period == '1day') { + //推送一天行情 + $day_kline = $symbol['kline_data']; + $day_kline['type'] = 'kline'; +// SendMarket::dispatch($day_kline)->onQueue('kline.all'); + //SendMarket::dispatch($symbol['kline_data'])->onQueue('kline.1day'); + //存入数据库 + CurrencyQuotation::getInstance($symbol['kline_data']['legal_id'], $symbol['kline_data']['currency_id']) + ->updateData([ + 'change' => $symbol['kline_data']['change'], + 'now_price' => $symbol['kline_data']['close'], + 'volume' => $symbol['kline_data']['volume'], + ]); + } else { + continue; + } + } + } + } + } + + private function getMillisecond() + { + list($pSppfwv, $hmvXQMv) = explode(' ', microtime()); + return (float)sprintf('%.0f', (floatval($pSppfwv) + floatval($hmvXQMv)) * (0 - 1352 + 42 * 56)); + } + + + protected function calcIncreasePair($kline_data) + { + $open = $kline_data['open']; + $close = $kline_data['close'];; + $change_value = bc_sub($close, $open); + $change = bc_mul(bc_div($change_value, $open), 100, 2); + return $change; + } + + //心跳响应 + protected function onPong($con, $data) + { + //echo '收到心跳包,PING:' . $data->ping . PHP_EOL; + $send_data = [ + 'pong' => $data->ping, + ]; + $send_data = json_encode($send_data); + $con->send($send_data); + //echo '已进行心跳响应' . PHP_EOL; + } + + public function ping($con) + { + $ping = time(); + //echo '进程' . $this->worker_id . '发送ping服务器数据包,ping值:' . $ping . PHP_EOL; + $send_data = json_encode([ + 'ping' => $ping, + ]); + $con->send($send_data); + // $this->pingTimer = Timer::add($this->server_time_out, function () use ($con) { + // $msg = '进程' . $this->worker_id . '服务器响应超时,连接关闭' . PHP_EOL; + // echo $msg; + // $this->close($msg); + // }, [], false); + } + + protected function onPing($con, $data) + { + $this->pingTimer && Timer::del($this->pingTimer); + $this->pingTimer = null; + //echo '进程' . $this->worker_id . '服务器正常响应中,pong:' . $data->pong. PHP_EOL; + } +}