input('orderId', 0); $order = MicroOrder::where(['id'=>$orderId,'user_id'=>$user_id])->first(); return $this->success($order); } /** * 取允许支付的币种 * * @return \Illuminate\Http\JsonResponse */ public function getPayableCurrencies() { $currencies = Currency::with('microNumbers') ->where('is_micro', 1) ->get(); $user = Users::getAuthUser(); $currencies->transform(function ($item, $key) use ($user) { // 追加上险种 $insurance_types = InsuranceType::where('currency_id', $item->id) ->get(); $item->setAttribute('insurance_types', $insurance_types); // 追加上用户的钱包 $wallet = UsersWallet::where('user_id', $user->id) ->where('currency', $item->id) ->first(); if ($wallet) { $micro_with_insurance = bc_add($wallet->micro_balance, $wallet->insurance_balance); $wallet->setAttribute('micro_with_insurance', $micro_with_insurance); } $item->setAttribute('user_wallet', $wallet); // 追加上用户买的保险 $user_insurance = UsersInsurance::where('user_id', $user->id) ->whereHas('insurance_type', function ($query) use ($item) { $query->where('currency_id', $item->id); })->where('status', 1)->first(); $item->setAttribute('user_insurance', $user_insurance); return $item; }); return $this->success($currencies); } /** * 獲取訂單結果 */ public function getResult(Request $request) { $id = $request->input('id', 0); if ($id) { $user_id = Users::getUserId(); $order = MicroOrder::where('user_id', $user_id)->where('id', $id)->where('status', 3)->first(); if(!empty($order)) { return $this->success($order); }else{ return $this->error('Not Settlement'); } } return $this->error('ID is must.'); } /** * 取到期时间 */ public function getSeconds() { $seconds = MicroSecond::where('status', 1)->get(); return $seconds->count() > 0 ? $this->success($seconds) : $this->error($seconds); } /** * 下单 * * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function submit(Request $request) { $user_id = Users::getUserId(); $type = $request->input('type', 0); $match_id = $request->input('match_id', 0); $currency_id = $request->input('currency_id', 0); $seconds = $request->input('seconds', 0); $number = $request->input('number', 0); $validator = Validator::make($request->all(), [ 'match_id' => 'required|integer|min:1', 'currency_id' => 'required|integer|min:1', 'type' => 'required|integer|in:1,2', 'seconds' => 'required|integer|min:1', 'number' => 'required|numeric|min:0', ], [], [ 'match_id' => '交易对', 'currency_id' => '支付币种', 'type' => '下单类型', 'seconds' => '到期时间', 'number' => '投资数额', ]); // return $this->error($match_id."---".$currency_id."---".$seconds."---".$number); try { $re = MicroSecond::where('seconds','=',$seconds)->first(); if($re===null){ return $this->error('参数错误'); } if($number<=0){ $message = "下注金额不可小于"; $message = str_replace('massage.', '', __("massage.$message")); return $this->error($message.$re['min_num']); } if($re['min_num']>'0' && $number < $re['min_num']){ $message = "下注金额不可小于"; $message = str_replace('massage.', '', __("massage.$message")); return $this->error($message.$re['min_num']); } //进行基本验证 throw_if($validator->fails(), new \Exception($validator->errors()->first())); $insurance_start = Setting::getValueByKey('insurance_start','09:00'); $insurance_end = Setting::getValueByKey('insurance_end','12:00'); $insurance_start_datetime = Carbon::parse(date("Y-m-d {$insurance_start}:00")); $insurance_end_datetime = Carbon::parse(date("Y-m-d {$insurance_end}:00")); $use_insurance = 0;//是否使用受保金额 $currency = Currency::find($currency_id); //在受保时间段的话 if (Carbon::now()->gte($insurance_start_datetime) && Carbon::now()->lte($insurance_end_datetime)) { if($currency->insurancable == 1){ $can_order = $this->canOrder($user_id, $currency_id, $number); if($can_order !== true){ throw new \Exception("下单失败:{$can_order}"); } $user_insurance = UsersInsurance::where('user_id', $user_id) ->whereHas('insurance_type', function ($query) use ($currency_id) { $query->where('currency_id', $currency_id); }) ->where('status', 1) ->where('claim_status', 0) ->first(); $use_insurance = $user_insurance->insurance_type->type;//1,正向。2,反向。 } } if ( ($currency->insurancable != 1 || $use_insurance == 0) //如果当前不在受保时间段内或者所返币种不支持保险 && $currency->micro_holdtrade_max > 0 && $this->getExistingOrderNumber($user_id, $currency_id) >= $currency->micro_holdtrade_max ) { throw new \Exception('下单失败:超过最大持仓笔数限制'); } $currency_match = CurrencyMatch::find($match_id); $currency_quotation = CurrencyQuotation::where('match_id', $match_id)->first(); // file_put_contents('/www/wwwroot/crypto/public/upload/w.txt',$match_id."---".json_encode($currency_quotation)); if(!$currency_match->is_open){ $message = "休市"; $message = str_replace('massage.', '', __("massage.$message")); return $this->error($message); } throw_unless($currency_quotation, new \Exception('当前未获取到行情')); $rkey = 'market.'.strtolower($currency_match->currency_name. $currency_match->legal_name).'.kline.1min'; $market = json_decode(Redis::get($rkey),true);//MarketHour::getLastEsearchMarket($currency_match->currency_name, $currency_match->legal_name, '1min'); $market=$market['tick']; //下单价格随机浮动,减少价格重复概率 $decimal = 0; $faker = \Faker\Factory::create(); if (stripos($currency_match->fluctuate_min, '.') !== false) { $fluctuate_min = rtrim($currency_match->fluctuate_min, '0'); //移除掉小数点后面右侧多余的0 $fluctuate_min = rtrim($fluctuate_min, '.'); //如果是整数再移除掉小数点 $decimal_index = stripos($fluctuate_min, '.'); //查找小数点的位置 if ($decimal_index !== false) { $decimal = strlen($fluctuate_min) - $decimal_index - 1; } } trim($currency_match->fluctuate_min, '0'); $float_diff = $faker->randomFloat($decimal, $currency_match->fluctuate_min, $currency_match->fluctuate_max); $price = $currency_quotation->now_price;//$market['close'] ?? // 暂时取消 2024-05-28 /* if (mt_rand(0, 1)) { $price = bc_add($price, $float_diff); } else { $price = bc_sub($price, $float_diff); } */ $order_data = [ 'user_id' => $user_id, 'type' => $type, 'match_id' => $match_id, 'currency_id' => $currency_id, 'seconds' => $seconds, 'price' => $price, 'number' => $number, 'use_insurance' => $use_insurance, ]; $order = MicroTradeLogic::addOrder($order_data); return $this->success($order); } catch (\Throwable $th) { //return $this->error('File:' . $th->getFile() . ',Line:' . $th->getLine() . ',Message:' . $th->getMessage()); return $this->error($th->getMessage()); } } public function lists(Request $request) { try { $user_id = Users::getUserId(); $limit = $request->input('limit', 10); $status = $request->input('status', -1); $match_id = $request->input('match_id', -1); //交易对ID $currency_id = $request->input('currency_id', -1); //支付币种ID $lists = MicroOrder::where('user_id', $user_id) ->when($status <> -1, function ($query) use ($status) { $query->where('status', $status); }) ->when($match_id <> -1, function ($query) use ($match_id) { $query->where('match_id', $match_id); }) ->when($currency_id <> -1, function ($query) use ($currency_id) { $query->where('currency_id', $currency_id); }) ->orderBy('id', 'desc') ->paginate($limit); $lists->each(function ($item, $key) { return $item->append('remain_milli_seconds'); }); /* $results = $lists->getCollection(); $results->transform(function ($item, $key) { return $item->append('remain_milli_seconds'); }); $lists->setCollection($results); */ return $this->success($lists); } catch (\Throwable $th) { return $this->error($th->getMessage()); } } /** * 获得秒合约下单规则 */ protected function getOrderRules($user_id, $currency_id, $user_insurance) { //默认规则 $insurance_rules_arr = $user_insurance->insurance_rules_arr; if(count($insurance_rules_arr) > 0){ foreach ($insurance_rules_arr as $rule){ if($user_insurance->amount >= $rule['amount']){ return $rule; } } } return $rule = [ 'place_an_order_max' => 500, 'existing_number' => 3 ]; } public function getOneById(Request $request){ try { $user_id = Users::getUserId(); $id = $request->input('id', 0); if($id<1){ return $this->error('参数错误'); } $status = 3; //1交易中 2平仓中 3已平仓 $data = MicroOrder::where('user_id', $user_id) ->when($status <> -1, function ($query) use ($status) { $query->where('status', $status); })->find($id); return $this->success($data); } catch (\Throwable $th) { return $this->error($th->getMessage()); } } /** * 获得该币种交易中的秒合约订单 */ protected function getExistingOrderNumber($user_id, $currency_id){ $count = MicroOrder::where('user_id', $user_id) ->where('status', MicroOrder::STATUS_OPENED) ->where('currency_id', $currency_id) ->count(); return $count; } /** * 受保时间段是否可以下单 */ protected function canOrder($user_id, $currency_id, $number) { //$user = Users::getById($user_id); //该币种是否购买了保险 $user_insurance = UsersInsurance::where('user_id', $user_id) ->whereHas('insurance_type', function ($query) use ($currency_id) { $query->where('currency_id', $currency_id); }) ->where('status', 1) ->where('claim_status', 0) ->first(); if(!$user_insurance){ return '尚未申购或理赔保险'; } $insurance_type = $user_insurance->insurance_type; if($insurance_type->is_t_add_1 == 1){ $user_insurance_created_at_date = Carbon::parse($user_insurance->created_at); if(Carbon::today()->isSameAs('Y-m-d',$user_insurance_created_at_date)){ return '申购的保险T+1生效'; } } //dd($insurance_type); //该用户该保险的对应的钱包。 $user_wallet = UsersWallet::where('user_id', $user_id) ->where('currency', $insurance_type->currency_id) ->first(); //受保资产为0不允许下单 if($user_wallet->insurance_balance == 0){ return '受保资产为零'; } switch ($insurance_type->type){ case 1: //受保金额小于等于此时不可以下单 $defective_amount = bc_mul($user_insurance->amount ,bc_div($insurance_type->defective_claims_condition, 100)); //正向险种,受保资产小于等于【条件1额度】,不允许下单 if($user_wallet->insurance_balance <= $defective_amount){ return '受保资产小于等于可下单条件'; } break; case 2: //反向险种,受保资产小于等于【条件2额度】,不允许下单 if($user_wallet->insurance_balance <= $insurance_type->defective_claims_condition2){ return '您已超过持仓限制,暂停下单。'; } break; default: return '未知的险种类型'; } $order_rules = $this->getOrderRules($user_id, $currency_id, $user_insurance); //dd($order_rules); if($number > $order_rules['place_an_order_max']){ return '超过最大持仓数量限制'; } $getExistingOrderNumber = $this->getExistingOrderNumber($user_id, $currency_id); if($getExistingOrderNumber >= $order_rules['existing_number']){ return '交易中的订单大于最大挂单数量'; } return true;//可以下单 } //秒合约平仓 public function microClose(){ $matchList = CurrencyMatch::where("is_display",1)->get(); foreach( $matchList as $data){ MicroTradeLogic::close($data["id"]); } } }