model = new \app\admin\model\app\AppContract; $this->view->assign("typeList", $this->model->getTypeList()); $this->view->assign("statusList", $this->model->getStatusList()); } /** * 一键平仓 - 关闭所有持仓中的合约订单 * 自动根据止盈(zy_price)/止损(zs_price)价格平仓: * - 做多(more): 当前价 >= 止盈价 → 以止盈价平仓; 当前价 <= 止损价 → 以止损价平仓 * - 做空(free): 当前价 <= 止盈价 → 以止盈价平仓; 当前价 >= 止损价 → 以止损价平仓 * - 其他情况以当前市场价平仓 */ public function closeall() { if (!$this->request->isPost()) { $this->error('请求方式错误'); } $admin_id = $this->auth->id; // 构建查询条件 $where = ['a.status' => '1']; // 非超级管理员只能平仓自己团队的订单 if ($admin_id > 1) { $user = Db::name("user")->where("admin_id", $admin_id)->find(); if ($user) { $where['u.path'] = ['like', $user['path'] . '%']; } } // 查询所有持仓中的合约 $contracts = Db::name('app_contract') ->alias('a') ->field('a.*,b.close,b.symbol') ->join('app_rate b', 'a.coin_id = b.id', 'left') ->join('fa_user u', 'a.user_id = u.id') ->where($where) ->select(); if (empty($contracts)) { $this->error('没有持仓中的订单'); } $shizhi = Config::get('site.shizhi'); $success_count = 0; $fail_count = 0; foreach ($contracts as $contract) { Db::startTrans(); try { $market_price = $contract['close']; // 当前市场价 $zy_price = floatval($contract['zy_price']); // 止盈价 // 一键平仓:强制以止盈价平仓(无止盈价则以市价) $pc_price = ($zy_price > 0) ? $zy_price : $market_price; $diffnum = $pc_price - $contract['price']; // 计算收益(与pingcang API保持一致) if ($contract['type'] == 'more') { $income = $diffnum * $contract['num'] * $shizhi; } else { if ($diffnum < 0) { $income = abs($diffnum) * $contract['num'] * $shizhi; } else { $income = 0 - $diffnum * $contract['num'] * $shizhi; } } $income = sprintf('%.6f', $income); // 获取用户钱包 $currency = Db::name('app_currency_user') ->field('num_lh,id') ->where('user_id', $contract['user_id']) ->where('curr_id', 1)->find(); if (!$currency) { $fail_count++; Db::rollback(); continue; } // 记录资金明细 $detailed = [ 'user_id' => $contract['user_id'], 'curr_id' => 1, 'price' => abs($income), 'cart' => $income > 0 ? '1' : '2', 'type' => '6', 'serial_no' => time() . mt_rand(1000, 9999), 'order_result' => 'result', 'description' => $income > 0 ? 'Contract Close Profit' : 'Contract Close Loss', 'createtime' => time(), 'notice' => 'Admin Force Close', 'before_num' => $currency['num_lh'], 'after_num' => $currency['num_lh'] + $income, ]; $detaileds = [$detailed]; $detaileds[] = [ 'user_id' => $contract['user_id'], 'curr_id' => 1, 'price' => $contract['promise_fee'], 'cart' => '1', 'type' => '6', 'serial_no' => time() . mt_rand(1000, 9999), 'order_result' => 'result', 'description' => 'Contract Margin Refund', 'createtime' => time(), 'notice' => 'Admin Force Close', 'before_num' => $detailed['after_num'], 'after_num' => $detailed['after_num'] + $contract['promise_fee'], ]; $lostnum = sprintf("%.6f", ($currency['num_lh'] + $income + $contract['promise_fee'])); // 更新钱包余额 Db::name('app_currency_user') ->where('id', $currency['id']) ->update(['num_lh' => $lostnum, 'updatetime' => time()]); // 更新订单状态:自动写入平仓价、平仓时间、收益 Db::name('app_contract') ->where('id', $contract['id']) ->update(['status' => '2', 'pc_price' => $pc_price, 'pctime' => time(), 'income' => $income]); // 写入资金明细 Db::name('app_detailed')->insertAll($detaileds); Db::commit(); $success_count++; } catch (\Exception $e) { Db::rollback(); $fail_count++; } } $this->success("一键平仓完成:成功 {$success_count} 笔,失败 {$fail_count} 笔"); } public function import() { parent::import(); } /** * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法 * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑 * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改 */ /** * 查看 */ public function index() { //设置过滤方法 $this->request->filter(['strip_tags']); if ($this->request->isAjax()) { //如果发送的来源是Selectpage,则转发到Selectpage if ($this->request->request('keyField')) { return $this->selectpage(); } // list($where, $sort, $order, $offset, $limit) = $this->buildparams(); $offset = $this->request->get("offset", 0); $limit = $this->request->get("limit", 0); $params = json_decode(input('filter'),true); $op = json_decode(input('op'),true); if(count($params) > 0){ $new_params = $new_op = []; foreach ($params as $key => $value) { if($key == 'mobile') { $new_params['u.' . $key] = $value; $new_op['u.' . $key] = $op[$key]; }else if($key == 'user_name'){ $new_params['u.nickname'] = $value; $new_op['u.nickname'] = $op[$key]; }elseif ($key == 'daili_name') { $new_params['e.nickname'] = $value; $new_op['e.nickname'] = $op[$key]; }else { $new_params['a.' . $key] = $value; $new_op['a.' . $key] = $op[$key]; } } $w = $this->rewriteQuery($new_params, $new_op); }else{ $w['a.id'] = array('>', 0); } $admin_id = $this->auth->id; if($admin_id > 1){ $user = Db::name("user")->where("admin_id",$admin_id)->find(); if($user){ $w['u.path'] = array("like",$user['path']."%"); } } $total = Db::name('app_contract') ->alias('a') ->field('a.*,u.nickname as user_name,e.nickname as daili_name') ->join('fa_user u', 'a.user_id = u.id') ->join('admin e', 'u.p_admin_id = e.id' , 'left') ->where($w) ->count(); $list = Db::name('app_contract') ->alias('a') ->field('a.*,u.nickname as user_name,b.coinname,b.symbol,b.close,e.nickname as daili_name') ->join('app_rate b','a.coin_id = b.id','left') ->join('fa_user u', 'a.user_id = u.id') ->join('admin e', 'u.p_admin_id = e.id' , 'left') ->where($w) ->order('a.id', 'desc') ->limit($offset, $limit) ->select(); foreach ($list as $key=>$value) { if($value['status'] == '1') { $diffnum = $value['close'] - $value['price']; if ($value['type'] == 'more') { //计算收益 $income = $diffnum / 100 * $value['num'] * $value['multiple'] * Config::get('site.shizhi'); } else { if ($diffnum < 0) { $income = abs($diffnum) / 100 * $value['num'] * $value['multiple'] * Config::get('site.shizhi'); } else { $income = 0 - $diffnum / 100 * $value['num'] * $value['multiple'] * Config::get('site.shizhi'); } } $value['income'] = sprintf('%.6f', $income); $list[$key] = $value; } } $result = array("total" => $total, "rows" => $list); return json($result); } return $this->view->fetch(); } }