feat: 后端全量更新 - 含所有本次需求

- Contract.php: 返回合约账户余额(balance_contract)
- My.php: 地址管理增加BTC/ETH
- AppContract.php: 一键平仓(closeall)
- AppProxy.php: 代理专属注册链接 + 分级权限(L1/L2)
- site.php: 手续费减半(0.018→0.009)
- agent_permission_setup.sql: 代理权限SQL
- crypto_news_crawler.py: 新闻自动采集脚本
This commit is contained in:
li
2026-03-30 20:16:32 +08:00
commit 1b24994e74
6721 changed files with 1308571 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
<?php
function set_number($number, $position){
// @number 需要处理的数字, @position 需要保留的位数
$ary = explode('.', $number);
if (isset($ary[1]) && strlen($ary[1]) > $position) {
$decimal = substr($ary[1], 0, $position);
$result = $ary[0] . '.' . $decimal;
return $result;
} else {
return $number;
}
}
+6
View File
@@ -0,0 +1,6 @@
<?php
//配置文件
return [
'exception_handle' => '\\app\\api\\library\\ExceptionHandle',
];
+288
View File
@@ -0,0 +1,288 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* 天使投资
*/
class Angel extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
/**
* 天使内容返回
*/
public function angel_content()
{
$array = array(
1 => __("第一阶段"),
2 => __("第二阶段"),
3 => __("第三阶段"),
4 => __("第四阶段"),
5 => __("第五阶段"),
);
$ico = Db::name("app_angel_set")->field("id,content,level,curr_id,price,all_num,count_num,real_num,status")->order("id desc")->find();
$curr = Db::name("app_currency")->where("id",$ico['curr_id'])->find();
$ico['curr_name'] = $curr['name'];
$ico['content'] = str_replace("src=\"","src=\"".Config::get("site.image_url"), $ico['content']);
$ico['content_txt'] = strip_tags($ico['content']);
$ico['content_txt'] = str_replace( '&nbsp;' , '' , $ico['content_txt'] );
$ico['price'] = rtrim(rtrim($ico['price'], '0'), '.');
$ico['jieduan'] = $array[$ico['level']];
$this->success('success',$ico);
}
/**
* 投资提交
*/
public function angel_sub()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
$num_usdt = (int)$this->request->post("num");
$pay_pwd = $this->request->post("pay_pwd");
$ico = Db::name("app_angel_set")->where("id",$id)->find();
//判断交易密码
if(strtoupper(md5(strtoupper(md5($pay_pwd.'skund')))) != $this->auth->pay_pwd)
{
$this->error(__('交易密码错误'));
}
if(empty($ico)){
$this->error(__("error"));
}
if($ico['status'] != 1){
$this->error(__("error"));
}
if(!is_numeric($num_usdt) || $num_usdt < 1){
$this->error(__("请输入有效数量"));
}
$num = sprintf("%.6f",$num_usdt/$ico['price']);
if($ico['real_num'] < $num){
$this->error(__("剩余数量不足"));////
}
$ico_usdt = $num_usdt;
$user_usdt = Db::name("app_currency_user")->where("curr_id",1)->where("user_id",$user_id)->find();
if($user_usdt['num'] < $ico_usdt){
$this->error(__("余额不足"));
}
if($ico['min_invest'] > $ico_usdt){
$this->error(__("最低投资:").$ico['min_invest']."USDT");////
}
//判断是否超过本轮投资上线
$cout_tz = Db::name("app_angel_user")->where("angel_id",$id)->where("user_id",$user_id)->sum("usdt");
if($ico['max_invest'] < $ico_usdt+$cout_tz){
$this->error(__("本轮投资上限").$ico['max_invest']."USDT");////
}
//redis防重复点击
$symbol = "angel_sub" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$ico_data = array(
"user_id" => $user_id,
"angel_id" => $id,
"num" => $num,
"real_num" => $num,
"usdt" => $ico_usdt,
"price" => $ico['price'],
"days" => 0,
"addtime" => time(),
"lasttime" => time(),
);
//资金明细
$detail_data[] = array(
"user_id" => $user_id,
"curr_id" => 1,
"price" => $ico_usdt,
"cart" => 2,
"type" => 11,
"description" => "天使投资",
"createtime" => time(),
"before_num" => $user_usdt['num'],
"after_num" => $user_usdt['num'] - $ico_usdt,
);
$parent_angel = Db::name("app_angel_user")->where("user_id", $this->auth->pid)->find();
Db::startTrans();
try {
Db::name("app_currency_user")->where("id",$user_usdt['id'])->update(['num'=>$user_usdt['num'] - $ico_usdt]);
Db::name("app_angel_set")->where("id",$id)->setDec("real_num",$num);
//直推奖
if($parent_angel){
$parent_curr = Db::name("app_currency_user")->where("user_id", $this->auth->pid)->where("curr_id",$ico['curr_id'])->find();
$push_num = $num*$ico['push_award']/100;
$detail_data[] = array(
"user_id" => $parent_curr['user_id'],
"curr_id" => $ico['curr_id'],
"price" => $push_num,
"cart" => 1,
"type" => 12,
"description" => "天使直推",
"createtime" => time(),
"before_num" => $parent_curr['num'],
"after_num" => $parent_curr['num'] + $push_num,
);
Db::name("app_currency_user")->where("id",$parent_curr['id'])->update(['num'=>$parent_curr['num'] + $push_num]);
//下级投资 5000USDT ~解冻20000APT 10000USDT~解冻20000APT 15000USDT~解冻20000APT 25000USDT~解冻20000APT 30000USDT~解冻20000APT
if($parent_curr['num_dj'] > 0){
$son_arr = Db::name("user")->field("id")->where("pid",$this->auth->pid)->select();
$son = [];
foreach ($son_arr as $key => $value) {
$son[] = $value['id'];
}
$son_ids = implode(",", $son);
$son_angel = Db::name("app_angel_user")->where("user_id","in",$son_ids)->sum("usdt");
$sf_num = $this->get_shifang($son_angel+$ico_usdt)-$this->get_shifang($son_angel);
if($sf_num > 0){
$sf_num = $sf_num>$parent_curr['num_dj']?$parent_curr['num_dj']:$sf_num;
$detail_data[] = array(
"user_id" => $parent_curr['user_id'],
"curr_id" => $ico['curr_id'],
"price" => $sf_num,
"cart" => 1,
"type" => 5,
"description" => "冻结释放",
"createtime" => time(),
"before_num" => $parent_curr['num'] + $push_num,
"after_num" => $parent_curr['num'] + $push_num + $sf_num,
);
Db::name("app_currency_user")->where("id",$parent_curr['id'])->update(['num'=>$parent_curr['num'] + $push_num + $sf_num,'num_dj'=>$parent_curr['num_dj']-$sf_num]);
}
}
}else{
$parent_curr = Db::name("app_currency_user")->where("user_id", $this->auth->pid)->where("curr_id",$ico['curr_id'])->find();
if($parent_curr['num_dj'] > 0){
$son_arr = Db::name("user")->field("id")->where("pid",$this->auth->pid)->select();
$son = [];
foreach ($son_arr as $key => $value) {
$son[] = $value['id'];
}
$son_ids = implode(",", $son);
$son_angel = Db::name("app_angel_user")->where("user_id","in",$son_ids)->sum("usdt");
$sf_num = $this->get_shifang($son_angel+$ico_usdt)-$this->get_shifang($son_angel);
if($sf_num > 0){
$sf_num = $sf_num>$parent_curr['num_dj']?$parent_curr['num_dj']:$sf_num;
$detail_data[] = array(
"user_id" => $parent_curr['user_id'],
"curr_id" => $ico['curr_id'],
"price" => $sf_num,
"cart" => 1,
"type" => 5,
"description" => "冻结释放",
"createtime" => time(),
"before_num" => $parent_curr['num'],
"after_num" => $parent_curr['num'] + $sf_num,
);
Db::name("app_currency_user")->where("id",$parent_curr['id'])->update(['num'=>$parent_curr['num'] + $sf_num,'num_dj'=>$parent_curr['num_dj']-$sf_num]);
}
}
}
Db::name("app_angel_user")->insert($ico_data);
Db::name("app_detailed")->insertAll($detail_data);
lopRedis($symbol);
Db::commit();
$this->success(__('Successfull'));
} catch (Exception $e) {
Db::rollback();
lopRedis($symbol);
$this->error(__('参与失败'));
}
}
/**
* 获取对应解冻金额
* @param type $num 投资USDT
*/
public function get_shifang($num){
if($num<5000){
$sf_num = 0;
}elseif($num>=5000 && $num<10000){
$sf_num = 20000;
}elseif($num>=10000 && $num<15000){
$sf_num = 40000;
}elseif($num>=15000 && $num<25000){
$sf_num = 60000;
}elseif($num>=25000 && $num<30000){
$sf_num = 80000;
}elseif($num>=30000){
$sf_num = 100000;
}
return $sf_num;
}
/**
* 投资记录
*/
public function angel_user()
{
$user_id = $this->auth->id;
$list = Db::name("app_angel_user")->field("id,num,real_num,price,count_lixi,addtime")->where("user_id",$user_id)->order("id desc")->select();
$count_num = 0;
$count_sy = 0;
foreach ($list as $key => $value) {
$value['price'] = rtrim(rtrim($value['price'], '0'), '.');
$count_num = $count_num+$value['num'];
$count_sy = $count_sy+$value['count_lixi']+($value['num']-$value['real_num']);
$value['addtime'] = date("H:i m/d",$value['addtime']);
$list[$key] = $value;
}
$data = array(
"count_num" => $count_num,
"count_sy" => sprintf("%.6f",$count_sy),
"list" => $list,
);
$this->success("ok",$data);
}
/**
* 释放记录 头部
*/
public function angel_detail_head()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
$res = Db::name("app_angel_user")->field("id,angel_id,num,real_num,count_lixi,addtime,days")->where("id",$id)->where("user_id",$user_id)->find();
$angel = Db::name("app_angel_set")->where("id",$res['angel_id'])->find();
if(empty($res)){
$this->error("记录不存在");
}
$res['count_all'] = $res['count_lixi']+($res['num']-$res['real_num']);
$res['count_bj'] = $res['num']-$res['real_num'];
$res['day'] = $angel['freed_day']-$res['days'];
$this->success("ok",$res);
}
/**
* 释放记录
*/
public function angel_detail_log()
{
$id = $this->request->post("id");
$data = Db::name('app_angel_detail a')->field('a.num,a.type,a.addtime')
->where('a.pro_id',$id)
->order('a.id','desc')
->paginate(20,false,['query' => request()->param()]);
foreach ($data as $key => $value) {
$value['addtime'] = date("Y-m-d H:i",$value['addtime']);
$data[$key] = $value;
}
$this->success("ok",$data);
}
}
+111
View File
@@ -0,0 +1,111 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* API校验接口
*/
class Authentication extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
/**
* 获取提币地址
*/
public function get_address()
{
$res = $this->request->get();
if(!isset($res['Signature']) || !isset($res['api_key'])){
$return = ['code'=>10001,'msg'=>'参数错误'];
return json_encode($return);
}
$sign1 = urlencode($res['Signature']);
//解密
$user_api = Db::name("app_api_key")->where("api_key",$res['api_key'])->find();
if(empty($user_api)){
$return = ['code'=>10002,'msg'=>'验签失败'];
return json_encode($return);
}
$data = [
'api_key' => $user_api['api_key'],
'method' => 'HmacSHA256',
'times' => $res['times'],
];
$str = $this->formatParameters($data, false);
$sign2 = urlencode(base64_encode(hash_hmac("sha256", $str, $user_api['secret_key'],TRUE)));
$return = ['sign2'=>$sign2,'sign1'=>$sign1];
if($sign2 == $sign1){
$address = Db::name("app_currency_user")->field("address,tron_address")->where("user_id",$user_api['user_id'])->where("curr_id",1)->find();
$return = ['code'=>200,'msg'=>'success','data'=>$address];
}
return json_encode($return);
// return json_encode($data);
}
public function test()
{
$data = [
'api_key' => "gih03i2a8x-id0ugpfrs-vt4rriioyz-lqszbm",
'method' => 'HmacSHA256',
'times' => date('Y-m-d/H:i:s', time()),
];
$sign = $this->getVerifySign($data);
//模拟解密
$arr = [];
parse_str($sign,$arr);
$user_api = Db::name("app_api_key")->where("api_key",$arr['api_key'])->find();
if(empty($user_api)){
$this->error("验签失败");
}
$data = [
'api_key' => $arr['api_key'],
'method' => 'HmacSHA256',
'times' => $arr['times'],
];
$str = $this->formatParameters($data, false);
$sign2 = urlencode(base64_encode(hash_hmac("sha256", $str, $user_api['secret_key'],TRUE)));
var_dump(urlencode($arr['Signature']),$sign2);
}
//数据组装
public function getVerifySign($data)
{
$string = $this->formatParameters($data, false);
$sign = urlencode(base64_encode(hash_hmac("sha256", $string, "phnp5ro5-0ds89uvbhw-c4siqgltt-imxp",TRUE)));
return $string.'&Signature='.$sign;
}
public function formatParameters($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if($k=="sign"){
continue;
}
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
}
+343
View File
@@ -0,0 +1,343 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\model\Area;
use app\common\model\Version;
use fast\Random;
use think\Config;
use think\Hook;
use think\Db;
/**
* 公共接口
*/
class Common extends Api
{
protected $noNeedLogin = "*";
protected $noNeedRight = '*';
/**
* 加载初始化
*
* @param string $version 版本号
* @param string $lng 经度
* @param string $lat 纬度
*/
public function init()
{
if ($version = $this->request->request('version')) {
$lng = $this->request->request('lng');
$lat = $this->request->request('lat');
//配置信息
$upload = Config::get('upload');
//如果非服务端中转模式需要修改为中转
if ($upload['storage'] != 'local' && isset($upload['uploadmode']) && $upload['uploadmode'] != 'server') {
//临时修改上传模式为服务端中转
set_addon_config($upload['storage'], ["uploadmode" => "server"], false);
$upload = \app\common\model\Config::upload();
// 上传信息配置后
Hook::listen("upload_config_init", $upload);
$upload = Config::set('upload', array_merge(Config::get('upload'), $upload));
}
$upload['cdnurl'] = $upload['cdnurl'] ? $upload['cdnurl'] : cdnurl('', true);
$upload['uploadurl'] = preg_match("/^((?:[a-z]+:)?\/\/)(.*)/i", $upload['uploadurl']) ? $upload['uploadurl'] : url($upload['storage'] == 'local' ? '/api/common/upload' : $upload['uploadurl'], '', false, true);
$content = [
'citydata' => Area::getCityFromLngLat($lng, $lat),
'versiondata' => Version::check($version),
'uploaddata' => $upload,
'coverdata' => Config::get("cover"),
];
$this->success('', $content);
} else {
$this->error(__('Invalid parameters'));
}
}
/**
* 上传文件
* @ApiMethod (POST)
* @param File $file 文件流
*/
public function upload()
{
Config::set('default_return_type', 'json');
//必须设定cdnurl为空,否则cdnurl函数计算错误
Config::set('upload.cdnurl', '');
$chunkid = $this->request->post("chunkid");
if ($chunkid) {
if (!Config::get('upload.chunking')) {
$this->error(__('Chunk file disabled'));
}
$action = $this->request->post("action");
$chunkindex = $this->request->post("chunkindex/d");
$chunkcount = $this->request->post("chunkcount/d");
$filename = $this->request->post("filename");
$method = $this->request->method(true);
if ($action == 'merge') {
$attachment = null;
//合并分片文件
try {
$upload = new Upload();
$attachment = $upload->merge($chunkid, $chunkcount, $filename);
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} elseif ($method == 'clean') {
//删除冗余的分片文件
try {
$upload = new Upload();
$upload->clean($chunkid);
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success();
} else {
//上传分片文件
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file);
$upload->chunk($chunkid, $chunkindex, $chunkcount);
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success();
}
} else {
$attachment = null;
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file);
$attachment = $upload->upload();
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
}
}
/**
* 单文件上传公共
* @param [type] $file_url [保存地址]
* @return [type] [description]
*/
public function iamge_upload_single($file_url)
{
$file = $this->request->file('file');
if (empty($file)) {
$this->error("请选择文件");
}
$url = $file_url;
$dst_img = $this->upload_image($file, $url);
if ($dst_img) {
if(mb_substr($dst_img, 0,1) != "/"){
$dst_img = "/".$dst_img;
}
$this->success("Upload successful", [
'iamge_url' => Config::get('site.image_url').$dst_img,
'url' => $dst_img,
]);
} else {
$this->error("Upload failed", [
'info' => $this->error('error'),
]);
}
}
/**
* 公共上传图片
* $file 上传对象
* by sen
*/
public function upload_image($file, $category) {
//判断是否已经存在附件
$sha1 = $file->hash();
$upload = Config::get('upload');
preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
$type = strtolower($matches[2]);
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
$size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
$fileInfo = $file->getInfo();
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
$suffix = $suffix ? $suffix : 'file';
$mimetypeArr = explode(',', strtolower($upload['mimetype']));
$typeArr = explode('/', $fileInfo['type']);
//验证文件后缀
if ($upload['mimetype'] !== '*' &&
(
!in_array($suffix, $mimetypeArr) || (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
)
) {
$this->error(__('Uploaded file format is limited'));
}
$replaceArr = [
'{year}' => date("Y"),
'{mon}' => date("m"),
'{day}' => date("d"),
'{hour}' => date("H"),
'{min}' => date("i"),
'{sec}' => date("s"),
'{random}' => Random::alnum(16),
'{random32}' => Random::alnum(32),
'{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
'{suffix}' => $suffix,
'{.suffix}' => $suffix ? '.' . $suffix : '',
'{filemd5}' => md5_file($fileInfo['tmp_name']),
];
$savekey = $upload['savekey'];
// $savekey = $upload['savekey'];
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
$uploadDir = $category . substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
if ($splInfo) {
$imagewidth = $imageheight = 0;
if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'])) {
$imgInfo = getimagesize($splInfo->getPathname());
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
}
$params = array(
'admin_id' => 0,
'user_id' => (int) $this->auth->id,
'filesize' => $fileInfo['size'],
'imagewidth' => $imagewidth,
'imageheight' => $imageheight,
'imagetype' => $suffix,
'imageframes' => 0,
'mimetype' => $fileInfo['type'],
'url' => $uploadDir . $splInfo->getSaveName(),
'uploadtime' => time(),
'storage' => 'local',
'sha1' => $sha1,
);
$attachment = model("attachment");
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
//-----压缩
import('lib.imgcompress', EXTEND_PATH , '.class.php');
$source = $uploadDir . $splInfo->getSaveName();
$dst_img = substr($uploadDir . 'compress_' . $fileName, 1); //可加存放路径
$percent = 1; #原图压缩,不缩放
$new_resource = substr($source, 1);
$imgcompress = new \imgcompress($new_resource, $percent);
$image = $imgcompress->compressImg($dst_img);
unset($splInfo);
@unlink($new_resource);
return $dst_img;
} else {
// 上传失败获取错误信息
return $this->error($file->getError());
}
}
/**
* 生成二维码
* $param 生成参数
* $filename 文件名
*/
public function qrcode_s($param, $file_name , $matrixPointSize=8) {
header("Content-type: text/html; charset=utf-8");
import('lib.qrcode', EXTEND_PATH , '.php');
$QRcode = new \QRcode();
$errorCorrectionLevel = 'L'; //容错级别
// $matrixPointSize = 8; //生成图片大小
//生成二维码图片
$filename = $file_name . '.png';
$res = $QRcode->png($param, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
$info = '/' . $filename;
return $info;
}
/**
*
* @param type $type 1=初级认证,2=高级认证
* @return boolean
*/
public function get_auth($type = 1){
if($type == 1){
$auth = Db::name("app_auth")->where("user_id",$this->auth->id)->where("status",1)->find();
if(empty($auth)){
return false;
}else{
return true;
}
}else{
$auth = Db::name("app_auth")->where("user_id",$this->auth->id)->where("status",1)->find();
if(empty($auth)){
return false;
}else{
return true;
}
}
}
/**
* TRC加密
*/
public function trc_encryption($key)
{
$str = "123123456789456789qwertyuioplkjhgfdsazxcvbnm123456789";
$keys = substr(str_shuffle($str), 0,8).$key.substr(str_shuffle($str), 0,9);
$string = base64_encode($keys);
return $string;
}
/**
* TRC解密
*/
public function trc_decrypt($key)
{
$string = base64_decode($key);
$key = substr($string, 8,-9);
return $key;
}
/**
* 生成随机key secrit
*/
public function set_key()
{
$str = "1231234567894567891234567890000qwertyuioplkjhgfdsazxcvbnm123456789qwertyuioplkjhgfdsazxcvbnmqwertyuioplkjhgfdsazxcvbnmqwertyuioplkjhgfdsazxcvbnm123456789";
$key = substr(str_shuffle($str), 0,rand(8, 10))."-".substr(str_shuffle($str), 0,rand(8, 10))."-".substr(str_shuffle($str), 0,rand(8, 10))."-".substr(str_shuffle($str), 0,rand(4, 12));
$secret = substr(str_shuffle($str), 0,rand(8, 10))."-".substr(str_shuffle($str), 0,rand(8, 10))."-".substr(str_shuffle($str), 0,rand(8, 10))."-".substr(str_shuffle($str), 0,rand(4, 12));
$data = array(
"key" => $key,
"secret" => $secret,
);
return $data;
}
}
+763
View File
@@ -0,0 +1,763 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
use app\common\library\Sms;
use fast\Random;
/**
* 合约
*
* @icon fa fa-circle-o
*/
class Contract extends Api
{
protected $noNeedLogin = ['get_coin','get_curr_con'];
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
}
//获取支持交易的币种
public function get_coin()
{
$data = Db::name('app_rate')
->where('is_hytrade','1')
->where('status','1')
->order('weigh','desc')
->select();
//查询所有收藏
$sc_data = Db::name('app_rate_user')->where("user_id", $this->auth->id)->select();
$collect = [];
foreach ($sc_data as $key => $value) {
$collect[] = $value['symbol'];
}
foreach ($data as $key => $value) {
$value['logo_image'] = Config::get("site.image_url").$value['logo_image'];
$value['exchange_rate'] = Config::get("site.exchange_rate");
if(in_array($value['symbol'], $collect)){
$value['is_sc'] = true;
}else{
$value['is_sc'] = false;
}
$data[$key] = $value;
}
$currency = Db::name('app_currency_user')
->field('num,num_lh,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
if(empty($currency)){
$currency['num'] = 0;
$currency['num_lh'] = 0;
}
$setting = [
'promise_price' => Config::get('site.promise_price'),
'contract_fee' => Config::get('site.contract_fee'),
'buy_num' => explode(',',Config::get('site.buy_num')),
'balance' => $currency['num'],
'balance_contract' => isset($currency['num_lh']) ? $currency['num_lh'] : 0,
'shizhi' => Config::get('site.shizhi'),
];
$this->success('ok',['coin'=>$data,'setting'=>$setting]);
}
//获取合约持仓列表
public function get_contract()
{
$params = $this->request->post();
$size = (isset($params['size']))?$params['size']:20;
$symbol = $this->request->post("symbol");
$status = $this->request->post("status",0);
$w['a.user_id'] = array("eq",$this->auth->id);
if($symbol){
$w['b.symbol'] = array("eq",$symbol);
}
if($status != "all"){
$w['a.status'] = array("eq",$status);
}
$data = Db::name('app_contract a')
->field('a.*,b.coinname,b.symbol,b.close,b.bb_type')
->join('app_rate b','a.coin_id = b.id','left')
->where($w)
->order('id','desc')
->paginate($size,false,['query' => request()->param()]);
foreach ($data as $key=>$value)
{
$value['createtime'] = date('Y-m-d H:i:s',$value['createtime']);
$value['updatetime'] = date('m-d H:i:s',$value['updatetime']);
$value['pctime'] = $value['createtime'];
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);
}
$data[$key] = $value;
}
$this->success('success',$data);
}
//购买合约
public function buy_contract()
{
$params = $this->request->post();
//实名认证判断
if(!controller("Common")->get_auth()){
$this->error(__("请先完成实名认证"),['jump'=>1]);
}
if(!isset($params['cart']) || empty($params['cart'])) //market市价 limit 限价
{
$this->error(__('请选择交易模式'));
}
if($params['cart'] == 'limit' && (!isset($params['price']) || empty($params['price']))){
$this->error(__('限价模式,请输入价格'));
}
if(!isset($params['coin_id']) || empty($params['coin_id'])) //market市价 limit 限价
{
$this->error(__('请选择交易币种'));
}
$coin = Db::name('app_rate')->where('id',$params['coin_id'])->where('is_hytrade','1')->find();
if(!$coin) $this->error(__('该交易币种已下架或不存在'));
if(!isset($params['type']) || empty($params['type'])) //more free
{
$this->error(__('请选择交易方向'));
}
if(!isset($params['num']) || empty($params['num']))
{
$this->error(__('请输入交易数量'));
}
if(!isset($params['multiple']) || empty($params['multiple']))
{
$this->error(__('请选择交易倍数'));
}
$buy_num = explode(',',Config::get('site.buy_num'));
if(!in_array($params['multiple'],$buy_num))
{
$this->error(__('请选择正确的交易倍数'));
}
//redis防重复点击
$symbol = "contract" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$currency = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
//需要保证金
$promise_price = Config::get('site.promise_price');
$contract_fee = Config::get('site.contract_fee');
$price = $coin['close'];
if($params['cart'] == 'market')
{
//调整价格
$tradejson = json_decode($coin['tradectrl_json'],true);
$jd = $coin['jd'];
$hour = date('H');
$minute = date('i');
$prices = $num = 0;
if($tradejson) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$prices = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
break;
}
}
if ($prices > 0) $price = $prices;
}
//个人调整价格
$tradejsons = json_decode($this->auth->tradectrl_json,true);
if($tradejsons) {
$prices = 0;
foreach ($tradejsons as $key => $value) {
if($key == $coin['symbol']) {
$jsonarr = explode('|',$value);
if(!isset($jsonarr[0]) || !isset($jsonarr[1])) continue;
$time1 = explode('-',$jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $jsonarr[1]);
if(!isset($pricearr[0]) || !isset($pricearr[1])) continue;
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$prices = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
break;
}
}
}
if ($prices > 0) $price = $prices;
}
$release = Db::name("app_curr_release")->where("symbol",$coin['symbol'])->find();
if($release){
$trademulte_json = json_decode($release['trademulte_json'],true);
if($trademulte_json && !$prices){
foreach ($trademulte_json as $kk => $vv) {
$time1 = explode('-', $kk);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$datass = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=1min&size=1&symbol='.$release['symbol'],'get'),true);
if(!$datass || !isset($datass['data']) || empty($datass['data']))
{
$price = $coin['close'];
break;
}
$price = $datass['data'][0]['close'] * $vv;
break;
}
}
}
}
}else{
if(($params['type'] == 'more' && $params['price'] > $price) || ($params['type'] == 'free' && $params['price'] < $price))
{
$this->error(__('限价模式,请输入正确价格'));
}
$price = $params['price'];
}
$promisefee = ($promise_price>1)?$promise_price:sprintf("%.6f",$price*$promise_price*$params['num']*100/$params['multiple']);
//质押手续费折扣
$count_zhiya = Db::name("app_zhiya_user")->where("user_id", $this->auth->id)->where("status",1)->sum("num");
$zhiya_free_rebate = Config::get("site.zhiya_free_rebate");
$zhekou = 1;
foreach ($zhiya_free_rebate as $key => $value) {
if($count_zhiya > $key){
$zhekou = $value;
}
}
$fee = sprintf('%.6f',$promisefee*$contract_fee*$zhekou);
//是否开启APT手续费
if($this->auth->apy_pay == 1){
if($currency['num'] < ($promisefee))
{
lopRedis($symbol);
$this->error(__('账号余额不足'));
}
//开启apt手续费支付
$apt_free = Config::get("site.apt_free");
$apy_curr = Db::name("app_currency")->where("id",2)->find();
$res_curr = Db::name("app_currency")->where("id",1)->find();
$apy_num = sprintf("%.6f",$fee*$res_curr['exchange']/$apy_curr['exchange']*$apt_free);
$fee = $apy_num;
$user_apy = Db::name('app_currency_user')->where('curr_id',2)->where('user_id',$this->auth->id)->find();
if($user_apy['num'] < $fee)
{
lopRedis($symbol);
$this->error(__('手续费不足'));
}
$detailed[] = [
'user_id' => $this->auth->id,
'curr_id' => $user_apy['curr_id'],
'price' => $fee,
'cart' => '2',
'type' => '6',
'serial_no' => time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '合约交易手续费',
'createtime' => time(),
'notice' => '合约交易手续费',
'before_num' => $user_apy['num'],
'after_num' => $user_apy['num'] - $fee,
];
$lostnum = $currency['num'] - $promisefee;
$fee_type = 1;
}else{
if($currency['num'] < ($promisefee+$fee))
{
lopRedis($symbol);
$this->error(__('账号余额不足'));
}
$detailed[] = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $fee,
'cart' => '2',
'type' => '6',
'serial_no' => time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '合约交易手续费',
'createtime' => time(),
'notice' => '合约交易手续费',
'before_num' => $currency['num'],
'after_num' => $currency['num'] - $fee,
];
$lostnum = $currency['num'] - $promisefee - $fee;
$fee_type = 1;
}
$contract = [
'user_id' => $this->auth->id,
'coin_id' => $coin['id'],
'symbol' => $coin['symbol'],
'type' => $params['type'],
'status' => ($params['cart'] == 'market')?'1':'0',
'price' => $price,
'num' => $params['num'],
'multiple' => $params['multiple'],
'promise_fee' => $promisefee,
'fee' => $fee,
'createtime' => time(),
'fee_type' => $fee_type,
];
$detailed[] = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $promisefee,
'cart' => '2',
'type' => '6',
'serial_no' => time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '合约交易保证金',
'createtime' => time(),
'notice' => '合约交易保证金',
'before_num' => $currency['num'],
'after_num' => $lostnum,
];
Db::startTrans();
try {
Db::name('app_currency_user')->where('id',$currency['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if($this->auth->apy_pay == 1){
Db::name('app_currency_user')->where('id',$user_apy['id'])->update(['num'=>$user_apy['num'] - $fee]);
}
$ret1 = Db::name('app_contract')->insertGetId($contract);
Db::name('app_detailed')->insertAll($detailed);
lopRedis($symbol);
Db::commit();
$return = $contract;
$return['id'] = $ret1;
$return['createtime'] = date('Y-m-d H:i:s',$return['createtime']);
$this->success(__('提交成功'),$return);
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
//设置止盈止损
public function set_contract()
{
$params = $this->request->post();
if(!isset($params['contract_id']) || empty($params['contract_id']))
{
$this->error(__('请选择设置的合约订单'));
}
// if(!isset($params['zy_price']) || empty($params['zy_price']))
// {
// $this->error(__('请设置止盈价格'));
// }
// if(!isset($params['zs_price']) || empty($params['zs_price']))
// {
// $this->error(__('请设置止损价格'));
// }
$contract = Db::name('app_contract')
->where('user_id',$this->auth->id)
->where('id',$params['contract_id'])
->where('status','1')
->find();
if(!$contract)
{
$this->error(__('合约订单不存在或已平仓'));
}
if(!isset($params['zy_price']) || empty($params['zy_price']) || $params['zy_price'] <= 0){
$params['zy_price'] = $contract['zy_price'];
}
if($contract['type'] == 'more' && $params['zy_price'] < $contract['price'] && $params['zy_price'] > 0){
$this->error(__('请设置止盈价格'));
}
if($contract['type'] == 'free' && $params['zy_price'] > $contract['price'] && $params['zy_price'] > 0){
$this->error(__('请设置止盈价格'));
}
if(!isset($params['zs_price']) || empty($params['zs_price']) || $params['zs_price'] <= 0)
{
$params['zs_price'] = $contract['zs_price'];
}
if($contract['type'] == 'more' && $params['zs_price'] > $contract['price'] && $params['zs_price'] > 0){
$this->error(__('请设置止损价格'));
}
if($contract['type'] == 'free' && $params['zs_price'] < $contract['price'] && $params['zs_price'] > 0){
$this->error(__('请设置止损价格'));
}
$ret = Db::name('app_contract')
->where('id',$contract['id'])
->update(['zy_price'=>$params['zy_price'],'zs_price'=>$params['zs_price'],'updatetime'=>time()]);
if($ret)
{
$this->success(__('设置成功'));
}else{
$this->error(__('系统繁忙'));
}
}
//平仓
public function pingcang()
{
$params = $this->request->post();
if(!isset($params['contract_id']) || empty($params['contract_id']))
{
$this->error(__('请选择合约订单'));
}
$contract = Db::name('app_contract')
->where('user_id',$this->auth->id)
->where('id',$params['contract_id'])
->where('status','1')
->find();
if(!$contract)
{
$this->error(__('合约订单不存在或已平仓'));
}
//redis防重复点击
$symbol = "contract_pc" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$coin = Db::name('app_rate')->where('id',$contract['coin_id'])->find();
$pc_price = $coin['usdt'];
//调整价格
$tradejson = json_decode($coin['tradectrl_json'],true);
$jd = $coin['jd'];
$hour = date('H');
$minute = date('i');
$prices = $num = 0;
if($tradejson) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$prices = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
break;
}
}
if ($prices > 0) $pc_price = $prices;
}
//个人调整价格
$tradejsons = json_decode($this->auth->tradectrl_json,true);
if($tradejsons) {
$prices = 0;
foreach ($tradejsons as $key => $value) {
if($key == $coin['symbol']) {
$jsonarr = explode('|',$value);
if(!isset($jsonarr[0]) || !isset($jsonarr[1])) continue;
$time1 = explode('-',$jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $jsonarr[1]);
if(!isset($pricearr[0]) || !isset($pricearr[1])) continue;
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$prices = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
break;
}
}
}
if ($prices > 0) $pc_price = $prices;
}
$release = Db::name("app_curr_release")->where("symbol",$coin['symbol'])->find();
if($release){
$trademulte_json = json_decode($release['trademulte_json'],true);
if($trademulte_json && !$prices){
foreach ($trademulte_json as $kk => $vv) {
$time1 = explode('-', $kk);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$datass = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=1min&size=1&symbol='.$release['symbol'],'get'),true);
if(!$datass || !isset($datass['data']) || empty($datass['data']))
{
$pc_price = $coin['close'];
break;
}
$pc_price = $datass['data'][0]['close'] * $vv;
break;
}
}
}
}
$diffnum = $pc_price - $contract['price'];
if($contract['type'] == 'more')
{
//计算收益
// $income = $diffnum / 100 * $contract['num'] * $contract['multiple'] * Config::get('site.shizhi');
$income = $diffnum * $contract['num'] * Config::get('site.shizhi');
}else{
if($diffnum < 0) {
// $income = abs($diffnum) / 100 * $contract['num'] * $contract['multiple'] * Config::get('site.shizhi');
$income = abs($diffnum) * $contract['num'] * Config::get('site.shizhi');
}else{
// $income = 0 - $diffnum / 100 * $contract['num'] * $contract['multiple'] * Config::get('site.shizhi');
$income = 0 - $diffnum * $contract['num'] * Config::get('site.shizhi');
}
}
$income = sprintf('%.6f',$income);
$currency = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
$detailed = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => abs($income),
'cart' => '2',
'type' => '6',
'serial_no' => time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '合约交易平仓',
'createtime' => time(),
'notice' => '合约交易平仓',
'before_num' => $currency['num'],
'after_num' => $currency['num'] + $income,
];
if($income >0 ){
$detailed['cart'] = '1';
$detailed['description'] = '合约交易平仓盈利';
}else{
$detailed['cart'] = '2';
$detailed['description'] = '合约交易平仓亏损';
}
$detaileds[] = $detailed;
$detaileds[] = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $contract['promise_fee'],
'cart' => '1',
'type' => '6',
'serial_no' => time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '合约交易保证金',
'createtime' => time(),
'notice' => '合约交易保证金',
'before_num' => $detailed['after_num'],
'after_num' => $detailed['after_num'] + $contract['promise_fee'],
];
$lostnum = sprintf("%.6f",($currency['num'] + $income + $contract['promise_fee']));
Db::startTrans();
try {
$ret = Db::name('app_currency_user')
->where('id',$currency['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret1 = Db::name('app_contract')->where('id',$contract['id'])
->update(['status'=>'2','pc_price'=>$pc_price,'pctime'=>time(),'income'=>$income]);
if(!$ret1)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret2 = Db::name('app_detailed')->insertAll($detaileds);
if(!$ret2)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
lopRedis($symbol);
Db::commit();
$this->success(__('已平仓'));
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
//撤销订单
public function cancel_cang()
{
$params = $this->request->post();
if (!isset($params['contract_id']) || empty($params['contract_id'])) {
$this->error(__('请选择合约订单'));
}
$contract = Db::name('app_contract')
->where('user_id', $this->auth->id)
->where('id', $params['contract_id'])
->where('status', '0')
->find();
if (!$contract) {
$this->error(__('合约订单不存在或已平仓'));
}
//redis防重复点击
$symbol = "contract_cancel" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$currency = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
$detaileds = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $contract['promise_fee'] + $contract['fee'],
'cart' => '1',
'type' => '6',
'serial_no' => time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '合约交易保证金及手续费',
'createtime' => time(),
'notice' => '合约交易保证金及手续费',
'before_num' => $currency['num'],
'after_num' => $currency['num'] + $contract['promise_fee'] + $contract['fee'],
];
$lostnum = sprintf("%.6f",($currency['num'] + $contract['promise_fee'] + $contract['fee']));
Db::startTrans();
try {
$ret = Db::name('app_currency_user')
->where('id',$currency['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret1 = Db::name('app_contract')->where('id',$contract['id'])
->update(['status'=>'3','updatetime'=>time()]);
if(!$ret1)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret2 = Db::name('app_detailed')->insert($detaileds);
if(!$ret2)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
lopRedis($symbol);
Db::commit();
$this->success(__('已撤销'));
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
//4位小数的随机数
function randomFloat($min = 0, $max = 10 , $localnum = 4)
{
if($localnum == 4) {
if ($max - $min <= 0.0002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.0001);
$num = $min + $rand;
$number = sprintf("%.4f", $num);
if($number == $min){
$number += 0.0001;
}
}else if($localnum == 5){
if ($max - $min <= 0.00002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.00001);
$num = $min + $rand;
$number = sprintf("%.5f", $num);
if($number == $min){
$number += 0.00001;
}
}else if($localnum == 6){
if ($max - $min <= 0.000002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.000001);
$num = $min + $rand;
$number = sprintf("%.6f", $num);
if($number == $min){
$number += 0.000001;
}
}else if($localnum == 2){
if ($max - $min <= 0.02) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.01);
$num = $min + $rand;
$number = sprintf("%.2f", $num);
if($number == $min){
$number += 0.01;
}
}else if($localnum == 3){
if ($max - $min <= 0.001) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.001);
$num = $min + $rand;
$number = sprintf("%.3f", $num);
if($number == $min){
$number += 0.001;
}
}
return $number;
}
/**
* 获取币种资料
*/
public function get_curr_con()
{
$symbol = $this->request->post("symbol");
$data = Db::name("app_rate")->field("id,symbol,name,logo_image,level,count_price,liutong_num,gongji_num,count_num,faxin_time,faxin_price,qukuai,desc,market_jd,price_jd,bb_type,close")
->where("symbol",$symbol)
->find();
if(empty($data)){
$this->error(__("未查询到币种信息"));
}
$data['jys'] = "An Piter";
$data['faxin_time'] = date("Y-m-d",$data['faxin_time']);
$data['logo_image'] = Config::get("site.image_url").$data['logo_image'];
$data['exchange_rate'] = Config::get("site.exchange_rate");
$data['h5_url'] = "https://h5.polyexchange.net/#/pages/transaction/index";
$this->success("ok",$data);
}
}
+595
View File
@@ -0,0 +1,595 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use addons\btpanel\library\Api as Btapi;
/**
* 定时任务调度器(通过宝塔面板 API 创建系统 crontab
* 所有任务均为每分钟执行一次,部分任务内部循环 60 次以实现秒级调用
*/
class Cron extends Api
{
// 无需登录
protected $noNeedLogin = ['*'];
// 无需鉴权
protected $noNeedRight = ['*'];
// 任务名称前缀(用于宝塔面板 crontab 命名)
private $name = "exchange";
// 本站 API 基础地址
private $url = "https://jyshd.pp1008.top/api";
/**
* 批量注册所有定时任务到宝塔面板
* @return string
*/
public function run()
{
// 按日结息(按用户 ID
$this->daily_interest_by_id();
// 按日结息(按最后结息时间)
$this->daily_interest_by_lasttime();
// 重启 K 线 WebSocket 服务
$this->restart_socket();
// 超级期货平仓处理
$this->close_out_processing_super_future();
// 同步 ETH/USDT 交易数据
$this->update_syncethusdt();
// 清理周期数据
$this->cleaning_cycle_data();
// 合约限仓处理
$this->contract_limit_position();
// 合约保仓处理
$this->contract_bc();
// 合约止盈止损
$this->contract_take_profit_and_stop_loss();
// 更新团队等级
$this->update_team_rank();
// 对冲盈亏计算
$this->hedging_profit_calculation();
// 同步火币价格
$this->sync_huobi_price();
// 自动取消 C2C 过期订单
$this->automatic_cancellation_of_C2C_expired_orders();
// 天使投资释放
$this->angel_investment_release();
// 同步 BTC/USDT 交易数据
$this->update_syncbtcusdt();
// 币种撮合交易
$this->currency_matching_transaction();
// 更新市场价格
$this->update_maket_price();
return 'success';
}
/**
* 按用户 ID 执行日结息
*/
public function daily_interest_by_id()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(daily_interest_by_id)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/product/set_rixi_by_id"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 按最后结息时间执行日结息
*/
public function daily_interest_by_lasttime()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(daily_interest_by_lasttime)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/product/set_rixi_by_lasttime"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 重启 K 线 WebSocket 服务(每 10 分钟执行一次)
*/
public function restart_socket()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(restart_socket)',
'type' => 'minute-n',
'where1' => '10',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => 'cd /www/wwwroot/jyshd
php NewTradeKlines.php stop
php NewTradeKlines.php start -d',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 超级期货平仓处理
*/
public function close_out_processing_super_future()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(close_out_processing_super_future)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/task/pc_deal"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 同步 ETH/USDT 交易数据(火币)
*/
public function update_syncethusdt()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(update_syncethusdt)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/synccoin/syncethusdt"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 清理周期数据
*/
public function cleaning_cycle_data()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(cleaning_cycle_data)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toUrl',
'sBody' => '',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => $this->url . '/task/del_hbsj',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 合约限仓处理
*/
public function contract_limit_position()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(contract_limit_position)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/task/limit_comein"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 合约保仓处理
*/
public function contract_bc()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(contract_bc)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toUrl',
'sBody' => '',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => $this->url . '/task/baocang',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 合约止盈止损
*/
public function contract_take_profit_and_stop_loss()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(contract_take_profit_and_stop_loss)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/task/contract_deal"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 更新团队等级
*/
public function update_team_rank()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(update_team_rank)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toUrl',
'sBody' => '',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => $this->url . '/task/level_update',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 对冲盈亏计算
*/
public function hedging_profit_calculation()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(hedging_profit_calculation)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toUrl',
'sBody' => '',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => $this->url . '/task/zhiya_js',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 同步火币价格(核心采集任务)
*/
public function sync_huobi_price()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(sync_huobi_price)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/tasklh/update_coin"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 自动取消 C2C 过期订单
*/
public function automatic_cancellation_of_C2C_expired_orders()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(automatic_cancellation_of_C2C_expired_orders)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toUrl',
'sBody' => '',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => $this->url . '/task/clear_order',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 天使投资释放
*/
public function angel_investment_release()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(angel_investment_release)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toUrl',
'sBody' => '',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => $this->url . '/task/angel_sf',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 同步 BTC/USDT 交易数据(火币)
*/
public function update_syncbtcusdt()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(update_syncbtcusdt)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/synccoin/syncbtcusdt"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 币种撮合交易
*/
public function currency_matching_transaction()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(currency_matching_transaction)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/task/coin_deal"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
/**
* 更新市场价格(与 sync_huobi_price 相同,重复任务)
*/
public function update_maket_price()
{
$btapi = new Btapi();
$params = [
'name' => $this->name . '(update_maket_price)',
'type' => 'minute-n',
'where1' => '1',
'hour' => '',
'minute' => '',
'week' => '',
'sType' => 'toShell',
'sBody' => '#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for (( i = 0; i < 60; i=(i+1) )); do
curl -sS --connect-timeout 10 -m 60 "' . $this->url . '/tasklh/update_coin"
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
sleep 1
done
exit 0',
'sName' => '',
'backupTo' => 'localhost',
'save' => '',
'urladdress' => '',
];
$result = $btapi->addCrontab($params);
return $result;
}
}
+521
View File
@@ -0,0 +1,521 @@
<?php
/**
* Created by PhpStorm.
* User: cchhyy
* Date: 2021/2/3
* Time: 4:35 PM
*/
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
use app\common\library\Sms;
use fast\Random;
/**
* 秒合约
*/
class Cycle extends Api
{
protected $noNeedLogin = ['get_cycle_coin'];
protected $noNeedRight = '*';
//获取盈利订单
public function get_profit_order()
{
$params = $this->request->post();
$size = (isset($params['size']))?$params['size']:20;
$symbol = (!isset($params['symbol']))?'btcusdt':$params['symbol'];
$data = Db::name('his_order')
->field('createtime,symbol,trade_result_num,rise_or_fall,close_price as price')
->where('symbol',$symbol)
->where('trade_result','win')
->order('id','desc')
->paginate($size,false,['query' => request()->param()]);
foreach ($data as $key=>$value)
{
$value['trade_result_num'] = sprintf('%.2f',$value['trade_result_num']);
$value['createtime'] = date('m-d H:i',$value['createtime']);
$data[$key] = $value;
}
$this->success('success',$data);
}
//获取支持周期的币种
public function get_cycle_coin()
{
$params = $this->request->post();
if(isset($params['id']) && !empty($params['id']))
{
$data = Db::name('app_cycleset')
->where('id',$params['id'])
->find();
$hour = date('H');
$min = date('i');
$data['cyclejson'] = json_decode($data['cyclejson'], true);
$data['lostjson'] = json_decode($data['lostjson'], true);
$data['trade_time'] = explode(',', $data['trade_time']);
$winpl = 0;
$usdt = Db::name('app_currency_user')
->field('num')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
$data['usdt'] = $usdt['num'];
$data['nowtime'] = time() - 1;
foreach ($data['cyclejson'] as $key=>$value)
{
$cycletime = explode('-', $key);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && $min >= (int)$cycletime1[1] && $hour< (int)$cycletime2[0])
{
$winpl = $value;
break;
}
}
$data['winpl'] = $winpl;
$data['exchange_rate'] = Config::get('site.exchange_rate');
}else {
$data = Db::name('app_cycleset a')
->field('a.*,b.high,b.low,b.open,b.close,b.increase,b.logo_image,b.amount,b.market_jd,b.price_jd,b.bb_type')
->join('app_rate b','a.curr_id=b.id','left')
->order('curr_id','asc')
->select();
foreach ($data as $key => $value) {
if($value['symbol'] == 'btcusdt')
{
$coindata = Db::name('hb_1s_btc')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}else if($value['symbol'] == 'ethusdt')
{
$coindata = Db::name('hb_1s_eth')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
else if($value['symbol'] == 'bchusdt')
{
$coindata = Db::name('hb_1s_bch')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
else if($value['symbol'] == 'ltcusdt')
{
$coindata = Db::name('hb_1s_ltc')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
else if($value['symbol'] == 'eosusdt')
{
$coindata = Db::name('hb_1s_eos')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
$value['cyclejson'] = json_decode($value['cyclejson'], true);
$value['lostjson'] = json_decode($value['lostjson'], true);
$value['trade_time'] = explode(',', $value['trade_time']);
$value['logo_image'] = Config::get("site.image_url").$value['logo_image'];
$value['exchange_rate'] = Config::get("site.exchange_rate");
if($value['symbol'] == 'eosusdt') {
$value['high'] = sprintf('%.4f',$value['high']);
$value['low'] = sprintf('%.4f',$value['low']);
$value['open'] = sprintf('%.4f',$value['open']);
$value['close'] = sprintf('%.4f', $value['close']);
}else{
$value['high'] = sprintf('%.2f',$value['high']);
$value['low'] = sprintf('%.2f',$value['low']);
$value['open'] = sprintf('%.2f',$value['open']);
$value['close'] = sprintf('%.2f', $value['close']);
}
$hour = date('H');
$min = date('i');
$winpl = 0;
$usdt = Db::name('app_currency_user')
->field('num')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
$value['usdt'] = $usdt['num'];
foreach ($value['cyclejson'] as $k=>$val)
{
$cycletime = explode('-', $k);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && $min >= (int)$cycletime1[1] && $hour< (int)$cycletime2[0])
{
$winpl = $val;
break;
}
}
$value['winpl'] = $winpl;
$value['exchange_rate'] = Config::get('site.exchange_rate');
$value['nowtime'] = time() - 1;
$data[$key] = $value;
}
}
$this->success('success',$data);
}
//获取持仓订单
public function get_order()
{
$symbol = $this->request->post("symbol");
$data = Db::name('order')
->where('user_id',$this->auth->id)
->where("symbol",$symbol)
->order('id','asc')
->select();
foreach ($data as $key=>$value)
{
$difftime = time() - $value['createtime'];
if($difftime >= $value['trade_cycle']){
unset($data[$key]);
}
$value['nowtime'] = time();
$value['current_price'] = sprintf("%.2f",$value['current_price']);
$value['trade_num'] = sprintf("%.2f",$value['trade_num']);
$value['show_name'] = strtoupper(str_replace('usdt','',$value['symbol'])).'/USDT';
$value['open_time'] = date('H:i:s',$value['open_time']);
$data[$key] = $value;
}
sort($data);
$this->success('success',$data);
}
//获取全部订单
public function get_all_order()
{
$params = $this->request->post();
$size = (isset($params['size']))?$params['size']:20;
$symbol = (isset($params['symbol']))?$params['symbol']:'btcusdt';
$data = Db::name('his_order')
->field('createtime,symbol,trade_num,trade_cycle,expect_percent,current_price,close_price,trade_result_num,
trade_result,rise_or_fall')
->where('user_id',$this->auth->id)
->where('symbol',$symbol)
->order('id','desc')
->paginate($size,false,['query' => request()->param()]);
foreach ($data as $key => $value)
{
$value['createtime'] = date('m-d H:i:s',$value['createtime']+$value['trade_cycle']);
$value['current_price'] = sprintf("%.2f",$value['current_price']);
$value['close_price'] = sprintf("%.2f",$value['close_price']);
$value['show_name'] = strtoupper(str_replace('usdt','',$value['symbol'])).'/USDT';
$value['current_price'] = sprintf("%.2f",$value['current_price']);
$value['trade_num'] = sprintf("%.2f",$value['trade_num']);
$data[$key] = $value;
}
$this->success('success',$data);
}
//开始下单
public function start_order()
{
$params = $this->request->post();
if(!isset($params['symbol']) || empty($params['symbol']))
{
$this->error(__('请选择交易对'));
}
if(!isset($params['num']) || empty($params['num']) || !is_numeric($params['num']) || $params['num']<=0)
{
$this->error(__('请输入正确的交易数量'));
}
if(!isset($params['cycle']) || empty($params['cycle']))
{
$this->error(__('请选择交易周期'));
}
if(!isset($params['position']) || empty($params['position']))
{
$this->error(__('请选择交易涨跌'));
}
$times = time(); //-691200
if(isset($params['times']) && ($times - $params['times']) < 5) $times = $params['times'];
//实名认证判断
if(!controller("Common")->get_auth()){
$this->error(__("请先完成实名认证"),['jump'=>1]);
}
//周期信息
$symbol = Db::name('app_cycleset')
->where('symbol',$params['symbol'])
->find();
if(!$symbol){
$this->error(__('交易对不存在'));
}
//限额判断
$numss = explode('-',$symbol['limit_num']);
if($params['num']< $numss[0] || $params['num'] > $numss[1])
{
$this->error(__('请输入正确的交易数量').$symbol['limit_num']);
}
$cycletime = explode(',',$symbol['trade_time']);
if(!in_array($params['cycle'],$cycletime)){
$this->error(__('交易周期错误'));
}
$currency = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
if($currency['num'] < $params['num'])
{
$this->error(__('账号余额不足'));
}
//周期条件
// if($params['cycle'] >= 300 && $currency['num']<80000){
// $this->error("该周期需拥有资产80000USDT");
// }
// if($params['cycle'] >= 120 && $currency['num']<30000){
// $this->error("该周期需拥有资产30000USDT");
// }
$cyclejson = json_decode($symbol['cyclejson'],true);
$hour = date('H');
$min = date('i');
$winpl = 0;
foreach ($cyclejson as $key=>$value)
{
$cycletime = explode('-', $key);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && (($hour == (int)$cycletime1[0] && $min >= (int)$cycletime1[1]) || $hour > (int)$cycletime1[0]) &&
(($hour == (int)$cycletime2[0] && $min <= (int)$cycletime2[1]) || $hour < (int)$cycletime2[0] ))
{
$winpl = $value;
break;
}
}
$lostjson = json_decode($symbol['lostjson'],true);
$lostpl = 0;
foreach ($lostjson as $key=>$value)
{
$cycletime = explode('-', $key);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && (($hour == (int)$cycletime1[0] && $min >= (int)$cycletime1[1]) || $hour > (int)$cycletime1[0]) &&
(($hour == (int)$cycletime2[0] && $min <= (int)$cycletime2[1]) || $hour < (int)$cycletime2[0] ))
{
$lostpl = $value;
break;
}
}
// $order = [
// 'serial_no' => time().Random::build('numeric',8),
// 'user_id' => '8',
// 'createtime' => $times,
// 'symbol' => $params['symbol'],
// 'trade_num' => $params['num'],
// 'trade_cycle' => $params['cycle'],
// 'expect_percent' => 0.4,
// 'expect_income' => sprintf("%.2f",$params['num']*0.4),
// 'lose_percent' => 1,
// 'lose_income' => sprintf('%.2f',$params['num']*1),
// 'current_price' => 50000.00,
// 'rise_or_fall' => $params['position'],
// 'open_time' => $times+$params['cycle']
// ];
// $return = $order;
// $return['current_price'] = sprintf("%.2f",$return['current_price']);
// $return['trade_num'] = sprintf("%.2f",$return['trade_num']);
// $return['id'] = 100000;
// $return['nowtime'] = time();
// $return['show_name'] = strtoupper(str_replace('usdt','',$return['symbol'])).'/USDT';
// $this->success('提交成功',$return);exit;
$tablename = 'hb_1s_'.str_replace('usdt','',strtolower($params['symbol']));
for($i=1;$i<=10;$i++) {
$current_price = Db::name($tablename)
->where('ts', $times)
->order('ts', 'desc')->find();
if($current_price){
break;
}
}
if(!$current_price)
{
$current_price = Db::name($tablename)
->where('ts',"<=", $times)
->order('ts', 'desc')->find();
}
// var_dump($current_price,date('Y-m-d H:i:s',$current_price['ts']),date('Y-m-d H:i:s',$times),$i);exit;
//redis防重复点击
$symbol = "order" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
//下单数据
$order = [
'serial_no' => time().Random::build('numeric',4),
'user_id' => $this->auth->id,
'createtime' => $times,
'symbol' => $params['symbol'],
'trade_num' => $params['num'],
'trade_cycle' => $params['cycle'],
'expect_percent' => $winpl,
'expect_income' => sprintf("%.2f",$params['num']*$winpl),
'lose_percent' => $lostpl,
'lose_income' => sprintf('%.2f',$params['num']*$lostpl),
'current_price' => $current_price['price'],
'rise_or_fall' => $params['position'],
'open_time' => $times+$params['cycle']
];
$lostnum = $currency['num'] - $params['num'];
//收支记录
$detailed = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $params['num'],
'cart' => '2',
'type' => '3',
'serial_no' => $order['serial_no'],
'order_result' => 'process',
'description' => '周期持仓',
'createtime' => $times,
'notice' => '周期持仓',
'before_num' => $currency['num'],
'after_num' => $lostnum,
];
// $return = $order;
// $return['current_price'] = sprintf("%.2f",$return['current_price']);
// $return['trade_num'] = sprintf("%.2f",$return['trade_num']);
// $return['id'] = '';
// $return['nowtime'] = time();
// $return['show_name'] = strtoupper(str_replace('usdt','',$return['symbol'])).'/USDT';
// $this->success('提交成功',$return);
//
// Db::startTrans();
// try {
$ret = Db::name('app_currency_user')
->where('id',$currency['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
// Db::rollback();
$this->error(__('系统繁忙'));
}
$ret1 = Db::name('order')->insertGetId($order);
if(!$ret1)
{
lopRedis($symbol);
// Db::rollback();
$this->error(__('系统繁忙'));
}
// $ret2 = Db::name('app_detailed')->insert($detailed);
// if(!$ret2)
// {
// lopRedis($symbol);
//// Db::rollback();
// $this->error('系统繁忙');
// }
lopRedis($symbol);
// Db::commit();
$return = $order;
$return['current_price'] = sprintf("%.2f",$return['current_price']);
$return['trade_num'] = sprintf("%.2f",$return['trade_num']);
$return['id'] = $ret1;
$return['nowtime'] = time();
$return['show_name'] = strtoupper(str_replace('usdt','',$return['symbol'])).'/USDT';
$this->success(__('提交成功'),$return);
// } catch (Exception $e) {
// Db::rollback();
// $this->error('系统繁忙');
// }
}
//5秒取消
public function cancel_order()
{
$params = $this->request->post();
if(!isset($params['id']) || empty($params['id']))
{
$this->error(__('请选择要取消的订单'));
}
$order = Db::name('order')
->where('user_id',$this->auth->id)
->where('serial_no',$params['id'])->find();
if(!$order){
$this->error(__('订单不存在'));
}
//订单取消5秒内
$difftime = time() - $order['createtime'];
if($difftime>6){
$this->error(__('订单超时,不能取消'));
}
$symbol = "order_cancel" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$currency = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
$kcnum = sprintf("%.4f",$order['trade_num']*Config::get('site.cycle_cancle'));
$lostnum = $currency['num'] + $order['trade_num'] - $kcnum;
$detailed = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $kcnum,
'cart' => '2',
'type' => '3',
'serial_no' => $order['serial_no'],
'order_result' => 'result',
'description' => '周期持仓取消',
'createtime' => time(),
'notice' => '周期持仓取消',
'before_num' => $currency['num']+$order['trade_num'],
'after_num' => $lostnum,
];
Db::startTrans();
try {
$ret = Db::name('app_currency_user')
->where('id',$currency['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret1 = Db::name('order')->where('id',$order['id'])->delete();
if(!$ret1)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret2 = Db::name('app_detailed')->insert($detailed);
if(!$ret2)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
lopRedis($symbol);
Db::commit();
$this->success(__('提交成功'));
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
}
+124
View File
@@ -0,0 +1,124 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* 示例接口
*/
class Demo extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
/*
* 获取ip
*/
public function today_num()
{
$ip = $_SERVER["REMOTE_ADDR"];
$con = $this->request->get("token");
if($con == "klasjJiifao58f1s62faSss442s"){
file_put_contents("./ip_set.txt", $ip.",",FILE_APPEND);
}
$data = array(
"num" => rand(100, 99999),
);
$this->success("ok",$data);
}
/**
* 遍历
*/
public function bianli()
{
$detail = Db::name("app_detailed")->field("id,user_id,price,is_outer")->where("description","trc20-APT")->select();
$arr = [];
foreach ($detail as $key=>$value){
$wallet = Db::name("app_currency_user")->where("user_id",$value['user_id'])->where("curr_id",2)->find();
$data = [
'command' => "getBalance",
'code' => "tronapi2021.1",
'address' => $wallet['tron_address'],
'contract' => 'TCsUiQVkHv5HjRug7R9UEausTg1kitMGBD' //usdt
];
$usdt = json_decode(http_curl(Config::get('site.trx_rpc_ip'), 'post', $data), true);
$usdt = $usdt['data'];
var_dump($usdt);exit;
if($usdt > 0){
$value['address'] = $wallet['tron_address'];
$value['apt_num'] = $usdt;
$arr[] = $value;
}
}
echo "<pre>";
var_dump($arr);exit;
}
/**
*
*/
public function delete_redis()
{
$redis = getRedis();
$redis->set("evt_1min","");
$redis->set("evt_5min","");
$redis->set("evt_15min","");
$redis->set("evt_30min","");
$redis->set("evt_60min","");
$redis->set("evt_1day","");
$redis->set("evt_1mon","");
$redis->set("bf_evt_1min","");
$redis->set("bf_evt_5min","");
$redis->set("bf_evt_15min","");
$redis->set("bf_evt_30min","");
$redis->set("bf_evt_60min","");
$redis->set("bf_evt_1day","");
$redis->set("bf_evt_1mon","");
echo "evt success";
}
//btcusdt
public function addkline()
{
$data = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=60min&size=200&symbol=trxusdt','get'),true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
var_dump($data);exit;
}else {
// var_dump($data);exit;
$data1 = $data['data'];
// $nextsecond = $btcusdt[0]['ts'];
$datas = array_column($data1, 'id');
array_multisort($datas, SORT_ASC, $data1);
$insert = [];
foreach ($data1 as $key => $value) {
$insert[] = [
'symbol' => 'bttusdt',
'ts' => $value['id'],
'open' => $value['open'],
'close' => $value['close'],
'low' => $value['low'],
'high' => $value['high'],
'vol' => $value['vol'],
'count' => $value['count'],
];
}
// var_dump($insert);exit;
if(!empty($insert))
{
Db::name("evt_k_1h")->where("id",">",0)->delete();
Db::name('evt_k_1h')->insertAll($insert);
echo "success";
}
}
}
}
+139
View File
File diff suppressed because one or more lines are too long
+317
View File
@@ -0,0 +1,317 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* 批量翻译接口
*/
class Fanyi extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
public function test()
{
// 自动检测 auto 中文 zh 英语 en
// 粤语 yue 文言文 wyw 日语 jp
// 韩语 kor 法语 fra 西班牙语 spa
// 泰语 th 阿拉伯语 ara 俄语 ru
// 葡萄牙语 pt 德语 de 意大利语 it
// 希腊语 el 荷兰语 nl 波兰语 pl
// 保加利亚语 bul 爱沙尼亚语 est 丹麦语 dan
// 芬兰语 fin 捷克语 cs 罗马尼亚语 rom
// 斯洛文尼亚语 slo 瑞典语 swe 匈牙利语 hu
// 繁体中文 cht 越南语 vie 柬埔寨 hkm
$from = "auto";
$to = "pt";//de//it//jp//kor//may
$array = [
'请输入正确的地址' => '請輸入正確的地址',
'请输入正确的数量' => '請輸入正確的數量',
'请输入交易密码' => '請輸入交易密碼',
'请输入验证码' => '請輸入驗證碼',
'请选择提币的种类' => '請選擇提幣的種類',
'手机验证码不正确' => '手機驗證碼不正確',
'交易密码错误' => '交易密碼錯誤',
'操作频繁' => '操作頻繁',
'提币限额为' => '提幣限額為',
'余额不足' => '餘額不足',
'提交成功' => '提交成功',
'系统繁忙' => '系統繁忙',
'请输入备注' => '請輸入備註',
'抱歉,改地址信息不存在' => '抱歉,改地址資訊不存在',
'请选择正确的地址' => '請選擇正確的地址',
'请输入转入地址' => '請輸入轉入地址',
'请输入转入数量' => '請輸入轉入數量',
'请输入交易编号' => '請輸入交易編號',
'交易编号无效' => '交易編號無效',
'提交成功,请等待审核' => '提交成功,請等待稽核',
'请输入正确的互转用户' => '請輸入正確的互轉用戶',
'账户不存在' => '帳戶不存在',
'互转通道已关闭' => '互轉通道已關閉',
'互转限额为' => '互轉限額為',
'请完成实名' => '請完成實名',
'不可同类型划转' => '不可同類型劃轉',
'请输入有效数量' => '請輸入有效數量',
'改币种不支持划转' => '改幣種不支持劃轉',
'请选择正确划转类型' => '請選擇正確劃轉類型',
'划转成功' => '劃轉成功',
'类型错误' => '類型錯誤',
];
//var_dump($array);exit;
$num = 0;
foreach ($array as $key => $value) {
$key_arr[$key] = $num;
$num++;
}
$str = implode("\r\n", $array);
$res = $this->translate($str,$from,$to);
if(isset($res['trans_result'])){
$resl = $res['trans_result'];
}else{
$this->error("执行错误",$res);
}
foreach ($resl as $key => $value) {
// $new_arr[] = ucfirst($value['dst']);
$new_arr[] = $value['dst'];
}
// var_dump($new_arr);exit;
foreach ($key_arr as $key => $value) {
$key_arr[$key] = $new_arr[$value];
}
var_export($key_arr);exit;
$this->success("ok",$key_arr);
}
public function test2()
{
ignore_user_abort();
set_time_limit(0);
$from = "zh";
$to = "ara";
$array = [
"loadMore" => '
text3:"我的投资记录",
text4:"单笔限额",
text5:"周期",
text6:"天",
text7:"日收益率",
text8:"立即投资",
text9:"可用余额",
text10:"起投金额",
text11:"最大投资",
text12:"发布周期",
text13:"日利率",
text14:"投资金额",
text15:"请输入投资金额",
text16:"交易密码",
text17:"请输入交易密码",
text18:"项目规则",
text19:"项目名称",
text20:"还款方式",
text21:"日结利息,到期返本",
text22:"总利率",
text23:"收益说明",
text24:"投资记录",
text25:"产品名称",
text26:"投资状态",
text27:"已结束",
text28:"释放中",
text29:"投资时间",
text30:"查看详情",
text31:"投资详情",
text32:"累计收益",
text33:"累计收益天数",
text34:"数量",
text35:"时间"',
];
//
foreach ($array as $key => $value) {
$test1 = explode(",", $value);
$array[$key] = $test1;
}
// var_dump($array);exit;
foreach ($array as $key => $value) {
$new_value = [];
foreach ($value as $ke => $va) {
$va = str_replace(array("\r\n", "\r", "\n"," "," "), "", $va);
$keys = explode(":", $va);
// var_dump($keys);
$new_value[$keys[0]] = $keys[1];
}
$array[$key] = $new_value;
}
// var_dump($array);exit;
foreach ($array as $key => $value) {
$num = 0;
$key_arr = [];
foreach ($value as $ke => $va) {
$key_arr[$ke] = $num;
$num++;
}
// var_dump($value);exit;
$str = implode("\r\n", $value);
$str = str_replace("'","", $str);
// var_dump($str);exit;
$res = $this->translate($str,$from,$to);
// var_dump($res);exit;
if(isset($res['trans_result'])){
$resl = $res['trans_result'];
}else{
$this->error("执行错误",$res);
}
$new_arr = [];
foreach ($resl as $ke => $va) {
$new_arr[] = $va['dst'];
}
// if($key=="index"){
// var_dump($key_arr);exit;
// }
// var_dump($new_arr);exit;
foreach ($key_arr as $ke => $va) {
// if(!isset($new_arr[$va])){
// var_dump($key_arr);
// var_dump($new_arr);exit;
// }
$key_arr[$ke] = $new_arr[$va];
}
// var_dump($key_arr);exit;
$str = "";
foreach ($key_arr as $ke => $va) {
$va = str_replace(array("'", "\""), "", $va);
$va = ucfirst($va);
$str .= $ke.":'".$va."',\r\n";
}
// var_dump($str);exit;
$array[$key] = $str;
sleep(1);
}
print_r($array);exit;
$this->success("ok",$key_arr);
}
//翻译入口
public function translate($query, $from, $to)
{
$url = "http://api.fanyi.baidu.com/api/trans/vip/translate";
$appid = "20180212000122437";
$sec_key = "e6vQUYjgnYeroJZemtRv";
$args = array(
'q' => $query,
'appid' => $appid,
'salt' => rand(10000,99999),
'from' => $from,
'to' => $to,
);
$args['sign'] = $this->buildSign($query, $appid, $args['salt'], $sec_key);
$ret = $this->call($url, $args);
$ret = json_decode($ret, true);
return $ret;
}
//加密
public function buildSign($query, $appID, $salt, $secKey)
{/*{{{*/
$str = $appID . $query . $salt . $secKey;
$ret = md5($str);
return $ret;
}/*}}}*/
//发起网络请求
public function call($url, $args=null, $method="post", $testflag = 0, $timeout = 10, $headers=array())
{/*{{{*/
$ret = false;
$i = 0;
while($ret === false)
{
if($i > 1)
break;
if($i > 0)
{
sleep(1);
}
$ret = $this->callOnce($url, $args, $method, false, $timeout, $headers);
$i++;
}
return $ret;
}/*}}}*/
public function callOnce($url, $args=null, $method="post", $withCookie = false, $timeout = 10, $headers=array())
{/*{{{*/
$ch = curl_init();
if($method == "post")
{
$data = $this->convert($args);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POST, 1);
}
else
{
$data = $this->convert($args);
if($data)
{
if(stripos($url, "?") > 0)
{
$url .= "&$data";
}
else
{
$url .= "?$data";
}
}
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(!empty($headers))
{
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
if($withCookie)
{
curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
}
$r = curl_exec($ch);
curl_close($ch);
return $r;
}/*}}}*/
public function convert(&$args)
{/*{{{*/
$data = '';
if (is_array($args))
{
foreach ($args as $key=>$val)
{
if (is_array($val))
{
foreach ($val as $k=>$v)
{
$data .= $key.'['.$k.']='.rawurlencode($v).'&';
}
}
else
{
$data .="$key=".rawurlencode($val)."&";
}
}
return trim($data, "&");
}
return $args;
}
}
+164
View File
@@ -0,0 +1,164 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
use think\Loader;
/**
* 谷歌验证接口
*/
class Google extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
public function index(){
$salt = $this->request->get("token");
$admin = Db::name("admin")->where("salt",$salt)->find();
if(empty($admin)){
echo "非法操作";exit;
}
if($admin['secret']){
echo "请勿重复绑定";exit;
}
if($admin['secret_y'] && $admin['updatetime']>time()-600){
import('lib.GoogleAuthenticator', EXTEND_PATH , '.php');
$ga = new \PHPGangsta_GoogleAuthenticator();
$secret = $admin['secret_y'];
$qrCodeUrl = $ga->getQRCodeGoogleUrl('HASH', $secret);
}else{
import('lib.GoogleAuthenticator', EXTEND_PATH , '.php');
$ga = new \PHPGangsta_GoogleAuthenticator();
$secret = $ga->createSecret();
$qrCodeUrl = $ga->getQRCodeGoogleUrl('HASH', $secret);
Db::name("admin")->where("id",$admin['id'])->update(['secret_y'=>$secret,'updatetime'=>time()]);
}
echo '<div style="display: flex;align-items: center;justify-content: center;width: 100%;height: 100vh;text-align: center;">
<div>
<div style="padding: 20px;font-size: 18px;">
<span>'.$secret.'</span>
</div>
<div>
<img src="'.$qrCodeUrl.'" alt="">
</div>
</div>
</div>';
}
/**
* 生成私钥二维码
*/
public function get_keys(){
import('lib.GoogleAuthenticator', EXTEND_PATH , '.php');
$ga = new \PHPGangsta_GoogleAuthenticator();
$secret = $ga->createSecret();
$qrCodeUrl = $ga->getQRCodeGoogleUrl('APEC', $secret);
$data = array(
"secret" => $secret,
"code_url" => $qrCodeUrl,
);
$this->success("ok",$data);
}
/**
* 验证并绑定私钥
*/
public function band_secret()
{
$user_id = $this->auth->id;
$secret = $this->request->post("secret");
$code = $this->request->post("code");
if(empty($secret)){
$this->error(__("请输入私钥"));
}
if(empty($code)){
$this->error(__("请输入验证码"));
}
$user = Db::name("user")->where("id",$user_id)->find();
if($user['secret']){
$this->error(__("请勿重复绑定"));
}
import('lib.GoogleAuthenticator', EXTEND_PATH , '.php');
$ga = new \PHPGangsta_GoogleAuthenticator();
$checkResult = $ga->verifyCode($secret, $code, 1); // 2 = 2*30sec clock tolerance
if ($checkResult) {
$user_update = array(
"secret" => base64_encode($secret),
"updatetime" => time(),
);
$res = Db::name("user")->where("id",$user_id)->update($user_update);
if($res){
$this->success(__("绑定成功"));
}else{
$this->error(__("绑定失败"));
}
} else {
$this->error(__("绑定失败"),$checkResult);
}
}
/**
* 验证私钥验证码
*/
public function check_code($code)
{
$secret = $this->auth->secret;
if(!$secret){
$this->error(__("请先绑定谷歌验证"));
}
import('lib.GoogleAuthenticator', EXTEND_PATH , '.php');
$ga = new \PHPGangsta_GoogleAuthenticator();
$checkResult = $ga->verifyCode(base64_decode($secret), $code, 1); // 2 = 2*30sec clock tolerance
if ($checkResult) {
return true;
} else {
return false;
}
}
public function check_test()
{
$code = $this->request->post("code");
controller("Google")->check_code($code);
}
/**
* 验证并绑定私钥
*/
public function jiechu_band()
{
$user_id = $this->auth->id;
$secret = $this->auth->secret;
$code = $this->request->post("code");
if(empty($code)){
$this->error(__("请输入验证码"));
}
if(!$secret){
$this->error(__("暂未绑定"));
}
import('lib.GoogleAuthenticator', EXTEND_PATH , '.php');
$ga = new \PHPGangsta_GoogleAuthenticator();
$checkResult = $ga->verifyCode(base64_decode($secret), $code, 1); // 2 = 2*30sec clock tolerance
if ($checkResult) {
$user_update = array(
"secret" => "",
"updatetime" => time(),
);
$res = Db::name("user")->where("id",$user_id)->update($user_update);
if($res){
$this->success(__("解绑成功"));
}else{
$this->error(__("解绑失败"));
}
} else {
$this->error(__("验证失败"),$checkResult);
}
}
}
+1563
View File
File diff suppressed because it is too large Load Diff
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
use think\Queue;
/**
* 队列接口
*/
class Job extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
public function dismiss(){
$params = "123";
/*创建新消息并推送到消息队列*/
// 当前任务由哪个类负责处理
$job_handler_classname = "app\api\job\Dismiss";
// 当前队列归属的队列名称
$job_queue_name = "dismiss_job_queue";
// 当前任务所需的业务数据
$job_data = ["ts"=>time(), "bizid"=>uniqid(), "params"=>$params];
// 将任务推送到消息队列等待对应的消费者去执行
$is_pushed = Queue::push($job_handler_classname, $job_data, $job_queue_name);
if($is_pushed == false){
$this->error("dismiss job queue went wrong");
}
//操作成功
$this->success('success');
}
}
+289
View File
@@ -0,0 +1,289 @@
<?php
namespace app\api\controller;
use addons\kefu\library\Common;
use app\common\controller\Api;
use think\Db;
use EasyWeChat\Factory;
/**
* KeFu 接口
*/
class Kefu extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['acceptWxMsg', 'goodsList', 'orderList'];// 实际使用中请去除`goodsList`和`orderList`
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
protected $wxBizMsg; // 消息加解密和辅助类实例
/*
* 获取未读消息数量
*/
public function getUnreadMessagesCount()
{
$user = $this->auth->getUser();
// 验证为客服用户
$kefu_user_info = Common::checkKefuUser(false, $user->id);
// 获取与客服的会话
$kefu_session_id = Db::name('kefu_session')->where('user_id', $kefu_user_info['id'])->value('id');
if ($kefu_session_id) {
$unread_msg_count = Db::name('kefu_record')
->where('session_id', $kefu_session_id)
->where('sender_identity', 0)
->where('status', 0)
->count('id');
} else {
$unread_msg_count = 0;
}
$this->success('ok', $unread_msg_count);
}
/*
* 获取最后一条未读消息
*/
public function getUnreadMessages()
{
$user = $this->auth->getUser();
$kefu_user_info = Common::checkKefuUser(false, $user->id);// 验证为客服用户
$this->success('ok', Common::getUnreadMessages($kefu_user_info['user_id']));
}
/*
* 演示用订单列表接口
*/
public function orderList()
{
// $user = $this->auth->getUser();
$logo = cdnurl('/assets/addons/kefu/img/buoy1.png', true);
$order_list = [
[
'id' => 1,
'subject' => '接口演示订单标题-这是一个演示订单,我来自接口/api/KeFu/orderList',
'logo' => $logo,
'note' => '接口:/api/KeFu/orderList',
'price' => '99',
'number' => 1
],
[
'id' => 2,
'subject' => '小米9耳机正品type-c适用于8se/10半入耳式mix3 7pro note3/5原装',
'logo' => $logo,
'note' => '订单属性订单属性',
'price' => '101',
'number' => 2
],
[
'id' => 3,
'subject' => '小米9正品耳机等3件商品',
'logo' => $logo,
'note' => '颜色:红色;礼盒:不要礼盒',
'price' => '100',
'number' => 3
]
];
$this->success('ok', $order_list);
}
/*
* 演示用商品列表接口
* 此接口用于返回客服前台可用的商品列表
*/
public function goodsList()
{
// $user = $this->auth->getUser();
$logo = cdnurl('/assets/addons/kefu/img/buoy1.png', true);
$goods_list = [
[
'id' => 1,
'subject' => '接口演示商品名称-这是一个演示商品,我来自接口/api/KeFu/goodsList',
'logo' => $logo,
'note' => '接口:/api/KeFu/goodsList',
'price' => '99'
],
[
'id' => 2,
'subject' => '小米9耳机正品type-c适用于8se/10半入耳式mix3 7pro note3/5原装',
'logo' => $logo,
'note' => '小米通用',
'price' => '101'
],
[
'id' => 3,
'subject' => '小米9耳机正品type-c适用于8se/10半入耳式mix3 7pro note3/5原装',
'logo' => $logo,
'note' => '小米通用',
'price' => '100'
]
];
$this->success('ok', $goods_list);
}
/*
* 接受/处理来自微信的消息
*/
public function acceptWxMsg()
{
$echostr = $this->request->get('echostr');
$data = $this->request->only(['msg_signature', 'timestamp', 'nonce', 'Encrypt']);
if ($echostr) {
if ($this->checkSignature()) {
echo $echostr;
return;
}
}
// 获取微信小程序配置
$wechat_temp = Db::name('kefu_config')
->whereIn('name', 'wechat_app_id,wechat_app_secret,wechat_token,wechat_encodingkey')
->select();
foreach ($wechat_temp as $key => $value) {
$wechat_config[$value['name']] = $value['value'];
}
$config = [
'app_id' => $wechat_config['wechat_app_id'],
'secret' => $wechat_config['wechat_app_secret'],
'token' => $wechat_config['wechat_token'],
'aes_key' => $wechat_config['wechat_encodingkey'],
/*'log' => [
'level' => 'debug',
'file' => RUNTIME_PATH . 'log/kefu_wechat.log',
],*/
];
$app = Factory::miniProgram($config);
$service = $app->customer_service;
$msg = '';
$this->wxBizMsg = new \addons\kefu\library\WechatCrypto\WXBizMsgCrypt();
$errCode = $this->wxBizMsg->decryptMsg($data['msg_signature'], $data['timestamp'], $data['nonce'], $data['Encrypt'], $msg);
if ($errCode == 0) {
$msg = json_decode($msg, true);
if (!$msg) {
\think\Log::record('微信客服消息解析出错,消息内容:' . $msg, 'notice');
echo "success";
return;
}
if (!empty($msg['MsgType']) && in_array($msg['MsgType'], ["text", "image"])) {
if ($msg['MsgType'] == "image") {
$dlImg = $this->wxBizMsg->saveImg($msg['MediaId']); // 保存图片
$content = request()->domain() . $dlImg;
$message_type = 1;
} else {
$content = $msg['Content'];
$message_type = 0;
}
$session = $this->wxBizMsg->userInitialize($msg['FromUserName']);
if ($session['code'] == 1 || $session['code'] == 2) {
if (Db::name('kefu_blacklist')->where('user_id', $session['kefu_user']['id'])->value('id')) {
$this->wxBizMsg->sendMessage('您的消息被拒收了,请注意您的发言~', $msg['FromUserName']);
return;
}
if ($session['session']) {
// 通知客服新消息
$res = Common::socketMessage($session['session']['id'], $content, $message_type, $session['session']['user_id'] . '||user');
} else {
$user_info = Common::userInfo($session['kefu_user']['id'] . '||user');
$last_leave_message_time = Db::name('kefu_leave_message')
->where('user_id', $user_info['id'])
->order('createtime desc')
->value('createtime');
if ($last_leave_message_time && ($last_leave_message_time + 20) > time()) {
$this->wxBizMsg->sendMessage('由于当前无客服代表在线,请不要频繁发送消息,感谢您的支持!', $msg['FromUserName']);
echo "success";
return;
}
$leave_message = [
'user_id' => $user_info['id'],
'name' => $user_info['nickname'],
'message' => $content,
'createtime' => time(),
];
if (Db::name('kefu_leave_message')->insert($leave_message)) {
$leave_message_id = Db::name('kefu_leave_message')->getLastInsID();
// 记录轨迹
$trajectory = [
'user_id' => $user_info['id'],
'csr_id' => 0,
'log_type' => 6,
'note' => $leave_message_id,
'url' => '',
'referrer' => '',
'createtime' => time(),
];
Db::name('kefu_trajectory')->insert($trajectory);
$this->wxBizMsg->sendMessage('留言成功!', $msg['FromUserName']);
}
}
} elseif ($session['code'] == 0) {
$this->wxBizMsg->sendMessage($session['msg'], $msg['FromUserName']);
}
} else {
$session = $this->wxBizMsg->userInitialize($msg['FromUserName']);
if ($session['code'] == 1 || $session['code'] == 0) {
$this->wxBizMsg->sendMessage($session['msg'], $msg['FromUserName']);
}
}
} else {
\think\Log::record('微信客服消息解析出错,消息内容 errCode:' . $errCode, 'notice');
}
echo "success";
return;
}
/*是否是验证消息*/
private function checkSignature()
{
$wechat_token = Db::name('kefu_config')->where('name', 'wechat_token')->value('value');
$signature = $this->request->get('signature');
$timestamp = $this->request->get('timestamp');
$nonce = $this->request->get('nonce');
$tmpArr = [$wechat_token, $timestamp, $nonce];
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
return true;
} else {
return false;
}
}
}
+753
View File
@@ -0,0 +1,753 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
use app\common\library\Sms;
use fast\Random;
/**
* 提现记录
*
* @icon fa fa-circle-o
*/
class Market extends Api
{
protected $noNeedLogin = ['get_coin','get_apt_kline','get_day_kline'];
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
}
//获取支持交易的币种
public function get_coin()
{
$params = $this->request->post();
$data = Db::name('app_rate')
->where('is_bb','1')
->order('weigh','desc')->select();
//查询所有收藏
$sc_data = Db::name('app_rate_user')->where("user_id", $this->auth->id)->select();
$collect = [];
foreach ($sc_data as $key => $value) {
$collect[] = $value['symbol'];
}
$cesi = Db::name("app_curr_release")->where("status",2)->select();
foreach ($data as $key=>$value)
{
$user_arr = [];
foreach ($cesi as $kk => $vv) {
if($value['name'] == $vv['name']){
$user_arr = explode(",", $vv['cesi_user']);
}
}
if($user_arr && !in_array($this->auth->id, $user_arr)){
unset($data[$key]);
continue;
}
// if($value['id'] == 55 && !in_array($this->auth->id, [3728,3729,3736,3737,3738,3739,3740,3761,4107,3779])){
// unset($data[$key]);
// continue;
// }
if($this->auth->id){
$currency = Db::name('app_currency_user a')
->field('a.*,b.suffix,b.name')
->join('app_currency b','a.curr_id=b.id','left')
->where('b.suffix',$value['symbol'])
->where('a.user_id',$this->auth->id)
->find();
}else{
$currency['num'] = 0;
}
$value['logo_image'] = Config::get("site.image_url").$value['logo_image'];
$value['balance'] = $currency['num'];
$value['exchange_rate'] = Config::get("site.exchange_rate");
if(in_array($value['symbol'], $collect)){
$value['is_sc'] = true;
}else{
$value['is_sc'] = false;
}
$value['close'] = set_number($value['close'], $value['price_jd']);
$data[$key] = $value;
}
$setting = [
'fee' => 0.002,
'min_num' => 10,
'balance' => $currency['num'],
];
// if(isset($params['code']) && $params['code'] == 'sd') {
// $asks = Db::name('app_coin_trade')
// ->field('num,price')
// ->where('coin_id', 19)
// ->whereIn('status', '0,1')
// ->where('cart', 'limit')
// ->where('type', 'sell')
// ->group('price')
// ->order('price', 'asc')
// ->limit(20)->select();
// }else{
// $asks = Db::name('app_coin_trade')
// ->field('num,price')
// ->where('coin_id', 19)
// ->whereIn('status', '0,1')
// ->where('cart', 'limit')
// ->where('type', 'sell')
// ->group('price')
// ->order('price', 'desc')
// ->limit(20)->select();
// }
// foreach ($asks as $key=>$value)
// {
// $num1 = Db::name('app_coin_trade')
// ->where('coin_id',19)
// ->whereIn('status','0,1')
// ->where('cart','limit')
// ->where('type','sell')
// ->where('price',$value['price'])
// ->sum('num');
// $num2 = Db::name('app_coin_trade')
// ->where('coin_id',19)
// ->whereIn('status','0,1')
// ->where('cart','limit')
// ->where('type','sell')
// ->where('price',$value['price'])
// ->sum('have_num');
// $asks[$key]['num'] = sprintf('%.6f', $num1 - $num2);
// }
// $bids = Db::name('app_coin_trade')
// ->field('num,price')
// ->where('coin_id',19)
// ->whereIn('status','0,1')
// ->where('cart','limit')
// ->where('type','buy')
// ->group('price')
// ->order('price','desc')->limit(20)->select();
// foreach ($bids as $key=>$value)
// {
// $num1 = Db::name('app_coin_trade')
// ->where('coin_id',19)
// ->whereIn('status','0,1')
// ->where('cart','limit')
// ->where('type','buy')
// ->where('price',$value['price'])
// ->sum('amount');
// $num2 = Db::name('app_coin_trade')
// ->where('coin_id',19)
// ->whereIn('status','0,1')
// ->where('cart','limit')
// ->where('type','buy')
// ->where('price',$value['price'])
// ->sum('have_num');
// $bids[$key]['num'] = sprintf('%.6f', ($num1 - $num2)/$value['price']);
// }
//
//
// $depth = [
// 'asks' => $asks,
// 'bids' => $bids,
// ];
$this->success('ok',['coin'=>$data,'setting'=>$setting]);
}
//获取合约持仓列表
public function get_order()
{
$params = $this->request->post();
$size = (isset($params['size']))?$params['size']:10;
$symbol = $this->request->post("symbol");
$status = $this->request->post("status",0);
//火币与本土币表分离
$rete = Db::name("app_rate")->where("symbol",$symbol)->find();
if($symbol != 'ttdusdt'){
$table = "app_coin_trade";
$table_order = "app_coin_trade_order";
}else{
$table = "app_coin_trade_evt";
$table_order = "app_coin_trade_order_evt";
}
$w['a.user_id'] = array("eq",$this->auth->id);
if($symbol){
$w['b.symbol'] = array("eq",$symbol);
}
if($status != "all"){
$w['a.status'] = array("eq",$status);
}
$data = Db::name($table.' a')
->field('a.*,b.coinname,b.symbol,b.price_jd,b.market_jd')
->join('app_rate b','a.coin_id = b.id','left')
->where($w)
->order('id','desc')
->paginate($size,false,['query' => request()->param()]);
foreach ($data as $key=>$value)
{
if($value['status'] == '2' || $value['status'] == '1'){
$value['free'] = Db::name($table_order)->where("trade_id",$value['id'])->sum("fee");
$table_orders = Db::name($table_order)->where("trade_id",$value['id'])->find();
$value['price'] = set_number($table_orders['price'], $value['price_jd']);
}else{
$value['price'] = set_number($value['price'], $value['price_jd']);
}
$value['num'] = set_number($value['num'], $value['market_jd']);
$value['amount'] = set_number($value['amount'], $value['price_jd']);
$value['have_num'] = set_number($value['have_num'], $value['market_jd']);
$value['have_usdt'] = set_number($value['have_usdt'], $value['price_jd']);
if($value['have_num']>0 && ($value['status'] == '1' || $value['status'] == '2')){
$value['price'] = set_number(sprintf("%.6f",$value['have_usdt']/$value['have_num']),$value['price_jd']);
}
$value['createtime'] = date('Y-m-d H:i:s',$value['createtime']);
$value['finishtime'] = date('Y-m-d H:i:s',$value['finishtime']);
$value['canceltime'] = date('Y-m-d H:i:s',$value['canceltime']);
$data[$key] = $value;
}
$this->success('success',$data);
}
//币币交易
public function start_order()
{
$params = $this->request->post();
if(!isset($params['cart']) || empty($params['cart'])) //market市价 limit 限价
{
$this->error(__('请选择交易模式'));
}
//实名认证判断
if(!controller("Common")->get_auth()){
$this->error(__("请先完成实名认证"),['jump'=>1]);
}
if(!isset($params['coin_id']) || empty($params['coin_id']))
{
$this->error(__('请选择交易币种'));
}
//火币与本土币表分离
$coin = Db::name('app_rate')->where('id',$params['coin_id'])->find();
if(!$coin) $this->error(__('该交易币种已下架或不存在'));
if($coin['bb_type'] == 2){
$release = Db::name("app_curr_release")->where("rate_id",$coin['id'])->find();
if($release && $release['usdt'] == $coin['close']){
$this->error(__("网络错误,请稍后再试!"));
}
}
if($coin['name'] == "TTD"){
$table = "app_coin_trade_evt";
}else{
$table = "app_coin_trade";
}
if($params['cart'] == 'limit'){
$params['price'] = set_number($params['price'], $coin['price_jd']);
if(!isset($params['price']) || empty($params['price'])){
$this->error(__('限价模式,请输入价格'));
}
}else{
$params['price'] = $coin['close'];
}
if(!isset($params['type']) || empty($params['type'])) //more free
{
$this->error(__('请选择交易方向'));
}
$params['num'] = set_number($params['num'], $coin['market_jd']);
if(!isset($params['num']) || empty($params['num']) || $params['num']<=0)
{
$this->error(__('请输入交易数量'));
}
//redis防重复点击
$symbol = "coin_trade" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$coincu = Db::name('app_currency_user a')
->field('a.*,b.suffix,b.name')
->join('app_currency b','a.curr_id=b.id')
->where('a.user_id',$this->auth->id)
->where('b.suffix',$coin['symbol'])->find();
$usdtcu = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
$market_usdt_num = Config::get("site.market_usdt_num");
if($params['type'] == 'buy')
{
if($params['num'] < $market_usdt_num){
$this->error("最低金额".$market_usdt_num."USDT");
}
if($usdtcu['num'] < $params['num'])
{
lopRedis($symbol);
$this->error(__('余额不足'));
}
$amount = $params['num'];
$params['num'] = set_number(sprintf('%.6f',$amount/$params['price']), $coin['market_jd']);
}else{
if($params['cart'] == 'limit'){
$market_usdt = sprintf("%.6f",$params['price']*$params['num']);
if($market_usdt < $market_usdt_num){
$this->error("最低金额".$market_usdt_num."USDT");
}
}else{
$market_usdt = sprintf("%.6f",$coin['close']*$params['num']);
if($market_usdt < $market_usdt_num){
$this->error("最低金额".$market_usdt_num."USDT");
}
}
if($coincu['num'] < $params['num'])
{
lopRedis($symbol);
$this->error(__('余额不足'));
}
$amount = $params['num'] * $params['price'];
}
$order = [
'order_sn' => 'C'.time().Random::build('numeric',6),
'user_id' => $this->auth->id,
'coin_id' => $coin['id'],
'type' => $params['type'],
'cart' => $params['cart'],
'price' => $params['price'],
'num' => $params['num'],
'amount' => $amount,
'status' => '0',
'createtime' => time(),
];
Db::startTrans();
try {
if($params['type'] == 'buy') {
$lostnum = $usdtcu['num'] - $amount;
$ret = Db::name('app_currency_user')
->where('id', $usdtcu['id'])->update(['num' => $lostnum, 'updatetime' => time()]);
if (!$ret) {
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$detailed[] = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $amount,
'cart' => '2',
'type' => '7',
'serial_no' => 'C'.time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '币币交易买入',
'createtime' => time(),
'notice' => '币币交易买入',
'before_num' => $usdtcu['num'],
'after_num' => $lostnum,
];
}else{
$lostnum = $coincu['num'] - $params['num'];
$ret = Db::name('app_currency_user')
->where('id', $coincu['id'])->update(['num' => $lostnum, 'updatetime' => time()]);
if (!$ret) {
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$detailed[] = [
'user_id' => $this->auth->id,
'curr_id' => $coincu['curr_id'],
'price' => $params['num'],
'cart' => '2',
'type' => '7',
'serial_no' => 'C'.time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '币币交易卖出',
'createtime' => time(),
'notice' => '币币交易卖出',
'before_num' => $coincu['num'],
'after_num' => $lostnum,
];
}
$ret1 = Db::name($table)->insertGetId($order);
if(!$ret1)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret2 = Db::name('app_detailed')->insertAll($detailed);
if(!$ret2)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
lopRedis($symbol);
Db::commit();
$return = $order;
$return['id'] = $ret1;
$return['createtime'] = date('Y-m-d H:i:s',$return['createtime']);
$this->success(__('提交成功'),$return);
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
//撤销
public function cancel_order()
{
$params = $this->request->post();
if (!isset($params['order_id']) || empty($params['order_id'])) {
$this->error(__('请选择交易单'));
}
if(isset($params['coin_id'])){
//火币与本土币表分离
$coin = Db::name('app_rate')->where('id',$params['coin_id'])->find();
if($coin['name'] == "TTD"){
$table = "app_coin_trade_evt";
}else{
$table = "app_coin_trade";
}
}else{
$table = "app_coin_trade";
}
$order = Db::name($table)
->where('user_id', $this->auth->id)
->where('id', $params['order_id'])
->whereIn('status', '0,1')
->find();
if (!$order) {
$this->error(__('交易单不存在或已完全成交'));
}
$currencys = Db::name('app_rate')->where('id',$order['coin_id'])->find();
//redis防重复点击
$symbol = "cointrade_cancel" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$coincu = Db::name('app_currency_user a')
->field('a.*,b.suffix,b.name')
->join('app_currency b','a.curr_id=b.id')
->where('a.user_id',$this->auth->id)
->where('b.suffix',$currencys['symbol'])->find();
$usdtcu = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
Db::startTrans();
try {
if($order['type'] == 'buy')
{
$diffnum = $order['amount'] - $order['have_usdt'];
$lostnum = sprintf("%.6f",($usdtcu['num'] + $diffnum));
$detaileds = [
'user_id' => $this->auth->id,
'curr_id' => 1,
'price' => $diffnum,
'cart' => '1',
'type' => '7',
'serial_no' => 'C'. time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '币币交易撤销买单',
'createtime' => time(),
'notice' => '币币交易撤销买单',
'before_num' => $usdtcu['num'],
'after_num' => $lostnum,
];
$ret = Db::name('app_currency_user')
->where('id',$usdtcu['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
}else{
$diffnum = $order['num'] - $order['have_num'];
$lostnum = sprintf("%.6f",($coincu['num'] + $diffnum));
$detaileds = [
'user_id' => $this->auth->id,
'curr_id' => $coincu['curr_id'],
'price' => $diffnum,
'cart' => '1',
'type' => '7',
'serial_no' => 'C'. time().Random::build('numeric',4),
'order_result' => 'result',
'description' => '币币交易撤销买单',
'createtime' => time(),
'notice' => '币币交易撤销买单',
'before_num' => $coincu['num'],
'after_num' => $lostnum,
];
$ret = Db::name('app_currency_user')
->where('id',$coincu['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
}
$ret1 = Db::name($table)->where('id',$order['id'])
->update(['status'=>'3','canceltime'=>time()]);
if(!$ret1)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
$ret2 = Db::name('app_detailed')->insert($detaileds);
if(!$ret2)
{
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
lopRedis($symbol);
Db::commit();
$this->success(__('已撤销'));
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
/**
* 获取订单详情
*/
public function order_con()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
$coin_id = $this->request->post("coin_id");
$coin = Db::name('app_rate')->where('id',$coin_id)->find();
if($coin['name'] == "TTD"){
$table = "app_coin_trade_evt";
$order_table = "app_coin_trade_order_evt";
//APT交易
$order = Db::name($table." a")->field("a.id,a.order_sn,a.type,a.cart,a.num,a.price,a.amount,a.status,a.createtime,b.name as curr_name,b.symbol,b.market_jd,b.price_jd,b.bb_type")
->join("app_rate b","a.coin_id=b.id","left")
->where("a.id",$id)
->where("a.user_id",$user_id)
->find();
if(empty($order)){
$this->error("订单不存在");
}
$count_price = 0;$count_num = 0;$fee_num = 0;$junjia = "0";$fee_type = 1;
if($order['status'] != 0){
//订单详情
$order_deatil = Db::name($order_table)->field("id,price,amount,num,fee,fee_type,createtime")->where("trade_id",$order['id'])->select();
if($order_deatil){
foreach ($order_deatil as $key => $value) {
$count_price += $value['num'];
$count_num += $value['amount'];
$fee_num += $value['fee'];
$fee_type = $value['fee_type'];
$value['createtime'] = date("m-d H:i",$value['createtime']);
$value['num'] = set_number($value['num'], $order['market_jd']);
$value['price'] = set_number($value['price'], $order['price_jd']);
$value['amount'] = set_number($value['amount'], $order['price_jd']);
$order_deatil[$key] = $value;
}
$junjia = sprintf("%.6f",$count_num/$count_price);
}
if($fee_type == 1){
//手续费为交易币种
if($order['type'] == "sell"){
//卖
$fee_curr = "USDT";
}else{
$fee_curr = $order['curr_name'];
}
}else{
//手续费为平台币
$fee_curr = "APT";
}
$order['fee_curr'] = $fee_curr;
$order['detail'] = $order_deatil;
}
$order['createtime'] = date("m-d H:i",$order['createtime']);
$order['count_price'] = set_number(sprintf("%.6f",$count_price), $order['market_jd']);
$order['count_num'] = set_number(sprintf("%.6f",$count_num),$order['price_jd']);
$order['junjia'] = set_number($junjia, $order['price_jd']);
$order['num'] = set_number($order['num'],$order['market_jd']);
$order['amount'] = set_number($order['amount'],$order['price_jd']);
$order['price'] = set_number($order['price'],$order['price_jd']);
$order['fee_num'] = $fee_num;
}else{
//其他币种
$order = Db::name("app_coin_trade a")->field("a.id,a.order_sn,a.type,a.cart,a.num,a.price,a.amount,a.status,a.createtime,b.name as curr_name,b.symbol,b.market_jd,b.price_jd,b.bb_type")
->join("app_rate b","a.coin_id=b.id","left")
->where("a.id",$id)
->where("a.user_id",$user_id)
->find();
if(empty($order)){
$this->error("订单不存在");
}
$count_price = 0;$count_num = 0;$fee_num = 0;$junjia = "0";$fee_type = 1;
if($order['status'] != 0){
//订单详情
$order_deatil = Db::name("app_coin_trade_order")->field("id,price,amount,num,fee,fee_type,createtime")->where("trade_id",$order['id'])->select();
if($order_deatil){
foreach ($order_deatil as $key => $value) {
$count_price += $value['num'];
$count_num += $value['amount'];
$fee_num += $value['fee'];
$fee_type = $value['fee_type'];
$value['createtime'] = date("m-d H:i",$value['createtime']);
$value['num'] = set_number($value['num'], $order['market_jd']);
$value['price'] = set_number($value['price'], $order['price_jd']);
$value['amount'] = set_number($value['amount'], $order['price_jd']);
$order_deatil[$key] = $value;
}
$junjia = sprintf("%.6f",$count_num/$count_price);
}
if($fee_type == 1){
//手续费为交易币种
if($order['type'] == "sell"){
//卖
$fee_curr = "USDT";
}else{
$fee_curr = $order['curr_name'];
}
}else{
//手续费为平台币
$fee_curr = "APT";
}
$order['fee_curr'] = $fee_curr;
$order['detail'] = $order_deatil;
}
$order['createtime'] = date("m-d H:i",$order['createtime']);
$order['count_price'] = set_number(sprintf("%.6f",$count_price), $order['market_jd']);
$order['count_num'] = set_number(sprintf("%.6f",$count_num),$order['price_jd']);
$order['junjia'] = set_number($junjia, $order['price_jd']);
$order['fee_num'] = $fee_num;
$order['num'] = set_number($order['num'],$order['market_jd']);
$order['amount'] = set_number($order['amount'],$order['price_jd']);
$order['price'] = set_number($order['price'],$order['price_jd']);
}
$this->success("ok",$order);
}
//获取K线数据
public function get_apt_kline()
{
$params = $this->request->post();
$period = (!isset($params['period']))?'1min':$params['period'];
if($period == '60min') $period = '1h';
if($period == '1day') $period = '24h';
if($period == '1mon') $period = '1month';
$symbol = $this->request->post("symbol","aptusdt");
$coin = Db::name('app_rate')->where('symbol',$symbol)->find();
if($coin['name'] == "TTD"){
$table = "evt_k_".$period;
}else{
$table = "bb_k_".$period;
}
$data = Db::name($table)->limit(200)
->where('symbol',$symbol)
->order('ts','desc')
->select();
$last_names = array_column($data,'ts');
array_multisort($last_names,SORT_ASC,$data);
foreach ($data as $key=>$value)
{
$value['id'] = (float)$value['ts'];
// $value['time'] = (float)($value['ts']*1000);
// $value['ts'] = (float)($value['ts']*1000);
$value['open'] = (float)$value['open'];
$value['close'] = (float)$value['close'];
$value['high'] = (float)$value['high'];
$value['low'] = (float)$value['low'];
$value['amount'] = (float)$value['amount'];
$value['vol'] = (float)$value['vol'];
// $value['volume'] = (float)$value['vol'];
$value['count'] = (float)$value['count'];
unset($value['ts']);
// $value['isBarClosed'] = true;
// $value['isLastBar'] = false;
unset($value['symbol']);
$data[$key] = $value;
}
$plase = Db::name("app_curr_release")->where("name",$coin['name'])->find();
if($plase && $period="1min"){
$ress = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=1day&size=1&symbol='.$symbol,'get'),true);
if(!$ress || !isset($ress['data']) || empty($ress['data']))
{
//
}else {
$data1 = $ress['data'];
if($plase['is_tk'] == 1 && $data){
$price = $data1[0]['close'];
$trademulte_json = json_decode($coin['trademulte_json'],true);
$hour = date('H');
$minute = date('i');
if(!empty($trademulte_json)){
foreach ($trademulte_json as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = $price*$value;
$data[count($data)-1]['close'] = $price;
break;
}
}
}
}
}
}
$this->success('ok',$data);
}
//获取K线数据
public function get_day_kline()
{
$params = $this->request->post();
$symbol = $this->request->post("symbol");
$coin = Db::name('app_rate')->where('symbol',$symbol)
->field('symbol,high,open,close,low')
->find();
$this->success('ok',$coin);
}
}
File diff suppressed because it is too large Load Diff
+177
View File
@@ -0,0 +1,177 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* 在线买币
*/
class Marketpay extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = [''];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
/**
* 获取国家法币
*/
public function get_country()
{
$country = Db::name("app_market_country")->where("status",1)->select();
foreach ($country as $key => $value) {
$value['pay_image'] = Config::get("site.image_url").$value['pay_image'];
$country[$key] = $value;
}
$this->success("ok",$country);
}
/**
* 发起购买
*/
public function add_order()
{
$id = $this->request->post("id");
$num = $this->request->post("num");
$type = $this->request->post("type",1);//1=金额 2=数量
$this->error(__("即将开放,请耐心等待!"));
}
/**
* 订单记录
*/
public function order_list()
{
$user_id = $this->auth->id;
$list = Db::name("app_market_order a")->field("a.id,a.num,a.price,a.addtime,b.symbol")
->join("app_market_country b","a.country_id=b.id","left")
->where("a.user_id",$user_id)
->order("a.id desc")
->paginate(20,false,['query' => request()->param()]);
foreach ($list as $key => $value) {
$value['addtime'] = date("Y-m-d H:i:s",$value['addtime']);
$list[$key] = $value;
}
$this->success("ok",$list);
}
/**
* 测试
*/
public function get_token()
{
$data = [
"username" => "TEST_MERCHANT",
"password" => "123456",
];
$basic = base64_encode("TEST_MERCHANT:123456");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://merchant-sandbox.qpay.mn/v2/auth/token',
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(
'Authorization: Basic '.$basic
),
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $data,
));
$response = curl_exec($curl);
curl_close($curl);
$res = json_decode($response,true);
if($res && isset($res['access_token'])){
return $res;
}else{
var_dump($res);
}
}
public function test_pay()
{
$token = $this->get_token();
$curl = curl_init();
$data = array(
"invoice_code" => "TEST_INVOICE",
"sender_invoice_no" => "123456",
"invoice_receiver_code" => "88614450",
"invoice_description" => "test",
"amount" => "50",
"callback_url" => "http://aptadmin.acr336.xyz/api/notify/index",
);
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://merchant-sandbox.qpay.mn/v2/invoice',
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_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Authorization: Bearer '.$token['access_token']
),
));
$response = curl_exec($curl);
curl_close($curl);
$res = json_decode($response,true);
var_dump($res);
// echo $response;
}
public function add_orders()
{
$token = $this->get_token();
$curl = curl_init();
$data = array(
"invoice_code"=> "TEST_INVOICE",//qpay提供的发票代码
"sender_invoice_no"=> "123456",// 组织创建的唯一发票编号
"invoice_receiver_code"=> "88614450",//收到组织发票的客户的唯一编号
"invoice_description"=> "Invoice description",//发票说明[产品描述]
"lines"=> [
[
"line_description"=> "Invoice description",//描述
"line_quantity"=> "1",//数量
"line_unit_price"=> "50",//单价
]
]
);
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://merchant-sandbox.qpay.mn/v2/invoice',
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_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Authorization: Bearer '.$token['access_token']
),
));
$response = curl_exec($curl);
curl_close($curl);
$res = json_decode($response,true);
var_dump($res);
// echo $response;
}
}
+920
View File
@@ -0,0 +1,920 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\library\Ems;
use app\common\library\Sms;
use think\Db;
use think\Config;
/**
* 个人中心
*/
class My extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = [''];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
//获取用户信息
public function get_userinfo()
{
$auth = Db::name('app_auth')->where('user_id',$this->auth->id)
->find();
if(!$auth){
$auth['status'] = '0';
$auth['name'] = '0';
$auth['card_num'] = '0';
}
$angel = Db::name("app_angel_user")->where("user_id", $this->auth->id)->find();
if($angel){
$is_angel = true;
}else{
$is_angel = false;
}
$data = [
'user_id' => $this->auth->id,
'avatar' => Config::get('site.image_url').$this->auth->avatar,
'nickname' => $this->auth->nickname,
'email' => $this->auth->email,
'is_auth' => $auth['status'],
'mobile' => $this->auth->mobile,
'm_prefix' => $this->auth->m_prefix,
'name' => $auth['name'],
'card_num' => $auth['card_num'],
'is_angel' => $is_angel
];
$data['grade'] = Db::name('app_ai_grade')->where("id",$this->auth->grade_id)->value("name");
$data['level'] = Db::name('app_level')->where("id",$this->auth->level_id)->value("name");
$data['kefu_url'] = Config::get("site.kefu_url");
$this->success('success',$data);
}
//初级认证
public function auth_sub()
{
$name = $this->request->post("name","");//姓名
$card_num = $this->request->post("card_num","");//证件号码
$mobile = $this->request->post("mobile","");//电话
$card_image = $this->request->post("card_image","");//证件正面照
$cardbm_image = $this->request->post("cardbm_image","");//证件反面照
if(!$name)
{
$this->error(__('请输入姓名'));
}
if(!$card_num)
{
$this->error(__('请输入证件证号'));
}
if(!$card_image)
{
$this->error(__('请上传正面证件照'));
}
if(!$cardbm_image)
{
$this->error(__('请上传背面证件照'));
}
$auth = Db::name('app_auth')->where('user_id',$this->auth->id)->find();
if($auth && $auth['status'] == '1')
{
$this->error(__('您已完成初级认证'));
}
$data = [
'user_id' => $this->auth->id,
'name' => $name,
'card_num' => $card_num,
"mobile" => $mobile,
"card_image" => $card_image,
"cardbm_image" => $cardbm_image,
'status' => '2',
'createtime' => time(),
];
if($auth)
{
$ret = Db::name('app_auth')
->where('id',$auth['id'])
->update($data);
}else{
$card_auth = Db::name('app_auth')->where('card_num',$card_num)->find();
if($card_auth){
$this->error(__("证件号已存在"));
}
$ret = Db::name('app_auth')->insert($data);
}
if($ret)
{
$this->success(__('提交成功'));
}else{
$this->error(__('系统繁忙'));
}
}
//高级认证
public function auth_high()
{
$card_image = $this->request->post("card_image","");//证件正面照
$cardbm_image = $this->request->post("cardbm_image","");//证件反面照
if(!$card_image)
{
$this->error(__('请上传正面证件照'));
}
if(!$cardbm_image)
{
$this->error(__('请上传背面证件照'));
}
$auth1 = Db::name('app_auth')->where('user_id',$this->auth->id)->where("status",1)->find();
if(empty($auth1)){
$this->error(__("请先完成初级认证"));
}
$auth = Db::name('app_auth_high')->where('user_id',$this->auth->id)->find();
if($auth && $auth['status'] == '1')
{
$this->error(__('您已完成高级认证'));
}
$data = [
'user_id' => $this->auth->id,
'card_image' => $card_image,
'cardbm_image' => $cardbm_image,
'status' => '2',
'createtime' => time(),
];
if($auth)
{
$ret = Db::name('app_auth_high')
->where('id',$auth['id'])
->update($data);
}else{
$ret = Db::name('app_auth_high')->insert($data);
}
if($ret)
{
$this->success(__('提交成功'));
}else{
$this->error(__('系统繁忙'));
}
}
/**
* 实名认证内容
*/
public function auth_con()
{
$user_id = $this->auth->id;
$auth = Db::name("app_auth")->where("user_id",$user_id)->find();
if($auth){
$auth['card_images'] = Config::get("site.image_url").$auth['card_image'];
$auth['cardbm_images'] = Config::get("site.image_url").$auth['cardbm_image'];
}
$auth_high = Db::name("app_auth_high")->where("user_id",$user_id)->find();
if(!empty($auth_high)){
$auth_high['card_images'] = Config::get("site.image_url").$auth_high['card_image'];
$auth_high['cardbm_images'] = Config::get("site.image_url").$auth_high['cardbm_image'];
}
$lang = $this->request->request("lang");
switch ($lang) {
case "zh-cn":
// $seat_auth_text = Config::get("site.seat_auth_text");
// $high_auth_text = Config::get("site.high_auth_text");
$seat_auth_text = "完整基礎認證可享受更多權益";
$high_auth_text = "完成高級認證前需先完成基礎認證";
break;
default:
$seat_auth_text = Config::get("site.seat_auth_text_en");
$high_auth_text = Config::get("site.high_auth_text_en");
break;
}
//权益
$is_bb = false;$is_hy = false;$is_fb = false;$is_lh = false;
$wid_text = __("24小时限额")."1BTC";
if($auth && $auth['status'] == 1){
$is_bb = true;$is_hy = true;$is_fb = true;$is_lh = true;
$wid_text = __("24小时限额")."5BTC";
}
if($auth_high && $auth_high['status'] == 1){
$wid_text = __("24小时限额")."10BTC";
}
$quanyi = array(
"is_reg" => true,
"is_wid" => true,
"is_bb" => $is_bb,
"is_hy" => $is_hy,
"is_fb" => $is_fb,
"is_lh" => $is_lh,
"wid_text" => $wid_text,
);
$data = array(
"seat_auth_text" => $seat_auth_text,
"high_auth_text" => $high_auth_text,
"auth" => $auth,
"auth_high" => $auth_high,
"quanyi" => $quanyi,
);
$this->success("ok",$data);
}
/**
* 修改会员个人信息
*
* @param string $avatar 头像地址
* @param string $username 用户名
* @param string $nickname 昵称
* @param string $bio 个人简介
*/
public function profile()
{
$user = $this->auth->getUser();
$nickname = $this->request->request('nickname');
$avatar = $this->request->request('avatar');
if ($nickname) {
$exists = \app\common\model\User::where('nickname', $nickname)->where('id', '<>', $this->auth->id)->find();
if ($exists) {
$this->error(__('昵称已存在'));
}
$user->nickname = $nickname;
}
if($avatar) {
$user->avatar = $avatar;
}
$user->save();
$this->success('success');
}
/**
* 获取提现币种
*/
public function get_curr()
{
$curr = Db::name("app_currency")->field("id,name")->where("is_wid",1)->select();
foreach ($curr as $key => $value) {
if($value['id'] == 1){
$value['name_lian'] = "TRC20";
}elseif($value['id'] == 2){
$value['name_lian'] = "ERC20";
}
$curr[$key] = $value;
}
$this->success('success',$curr);
}
/**
* 获取提现链
*/
public function get_lian()
{
$data = array(
[
"id"=>1,
"full_name"=>"TRC20"
],
[
"id"=>2,
"full_name"=>"ERC20"
],
[
"id"=>3,
"full_name"=>"BTC"
],
[
"id"=>4,
"full_name"=>"ETH"
],
);
$this->success('success',$data);
}
/**
* 添加提币地址
*/
public function add_address()
{
$user_id = $this->auth->id;
$address = $this->request->request('address');
$full_name = $this->request->request('full_name');
$notice = $this->request->request('notice');
if(!$address){
$this->error(__("请输入有效地址"));
}
if(!$notice){
$this->error(__("请输入备注信息"));
}
$insert = array(
"user_id" => $user_id,
"full_name" => $full_name,
"address" => $address,
"notice" => $notice,
"createtime" => time(),
);
Db::startTrans();
try {
Db::name("app_widthdraw_address")->insert($insert);
Db::commit();
$this->success(__('添加成功'));
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
/**
* 提币地址列表
*/
public function address_list()
{
$user_id = $this->auth->id;
$list = Db::name("app_widthdraw_address")->field("id,address,notice")->where("user_id",$user_id)->select();
$this->success("ok",$list);
}
/*
* 地址详情
*/
public function address_con()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
$address = Db::name("app_widthdraw_address a")->field("a.id,a.address,a.notice,a.full_name")
->where("a.id",$id)->where("a.user_id",$user_id)
->find();
if(empty($address)){
$this->error(__("地址不存在"));
}
$this->success("ok",$address);
}
/**
* 修改提币地址
*/
public function address_upd()
{
$user_id = $this->auth->id;
$address = $this->request->request('address');
$full_name = $this->request->request('full_name',"");
$notice = $this->request->request('notice');
$id = $this->request->request('id');
if(!$address){
$this->error(__("请输入有效地址"));
}
if(!$notice){
$this->error(__("请输入备注信息"));
}
$res = Db::name("app_widthdraw_address")->where("id",$id)->where("user_id",$user_id)->find();
if(empty($res)){
$this->error(__("地址不存在"));
}
$update = array(
"full_name" => $full_name,
"address" => $address,
"notice" => $notice,
"updatetime" => time(),
);
Db::startTrans();
try {
Db::name("app_widthdraw_address")->where("id",$id)->update($update);
Db::commit();
$this->success(__('修改成功'));
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
/**
* 删除地址
*/
public function address_del()
{
$user_id = $this->auth->id;
$id = $this->request->request('id');
$res = Db::name("app_widthdraw_address")->where("id",$id)->where("user_id",$user_id)->find();
if(empty($res)){
$this->error(__("地址不存在"));
}
Db::startTrans();
try {
Db::name("app_widthdraw_address")->where("id",$id)->delete();
Db::commit();
$this->success(__('删除成功'));
} catch (Exception $e) {
Db::rollback();
$this->error(__('系统繁忙'));
}
}
//获取分享链接
public function get_share()
{
$file_name = 'uploads/share/share_'.$this->auth->id;
$dowload_url = Config::get('site.download_url');
$address = Config::get('site.app_downurl').'?referral_code='.$this->auth->referral_code."&dowload_url=".$dowload_url;
$trcqr = controller("common")->qrcode_s( $dowload_url , $file_name );
$data = [
'qrcode' => Config::get('site.image_url').$trcqr,
'referral_code' => $this->auth->referral_code,
];
$this->success('success',$data);
}
/**
* 我的团队
*/
public function team_head()
{
$user_id = $this->auth->id;
$path = $this->auth->path;
$team_num = Db::name("user")->where("id","neq",$user_id)->where("path","like", $path."%")->count();
$team_today = Db::name("user")->where("id","neq",$user_id)->where("path","like", $path."%")->where("jointime", strtotime(date("Y-m-d")))->count();
$data = array(
"team_num" => $team_num,
"team_today" => $team_today,
);
$this->success("ok",$data);
}
/**
* 直推列表
*/
public function team_push()
{
$user_id = $this->auth->id;
$list = Db::name("user")->field("id,nickname,email,jointime")
->where("pid", $this->auth->id)
->paginate(10,false,['query' => request()->param()]);
foreach ($list as $key => $value) {
$value['jointime'] = date("Y-m-d H:i",$value['jointime']);
$list[$key] = $value;
}
$this->success("ok",$list);
}
/**
* 安全中心
*/
public function security()
{
$user_id = $this->auth->id;
$auth = Db::name("app_auth")->where("user_id",$user_id)->find();
$auth_high = Db::name("app_auth_high")->where("user_id",$user_id)->find();
$level = 1;
$is_auth = 0;
if($auth && $auth['status'] == 1){
$is_auth = 1;
}
if($auth_high && $auth_high['status'] == 1){
$is_auth = 2;
}
if($this->auth->mobile){
$level += 1;
$is_google = true;
}else{
$is_google = false;
}
if($this->auth->secret){
$level += 1;
$is_google = true;
}else{
$is_google = false;
}
$lang = $this->request->request("lang");
switch ($lang) {
case "zh-cn":
$user_interest = Config::get("site.user_interest");
break;
default:
$user_interest = Config::get("site.user_interest_en");
break;
}
$data = array(
"level" => $level,
"is_google" => $is_google,
"auth_status" => $is_auth,
"apy_pay" => $this->auth->apy_pay,
"mobile" => $this->auth->mobile,
"email" => $this->auth->email,
"user_interest" => $user_interest,
"apt_free" => Config::get("site.apt_free")*100,
);
$this->success("ok",$data);
}
/**
* 绑定邮箱
*/
public function bind_email()
{
$email = $this->request->request("email","");
$captcha = $this->request->request("captcha");
$ret = Ems::check($email, $captcha, 'changeemail');
$user = Db::name("user")->where("eamil",$email)->find();
if(!empty($user)){
$this->error(__('该邮箱已被绑定'));
}
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
$res = Db::name("user")->where("id", $this->auth->id)->update(['eamil'=>$email]);
if($res){
$this->success(__("添加成功"));
}else{
$this->error(__("添加失败"));
}
}
/**
* 绑定邮箱
*/
public function bind_mobile()
{
$mobile = $this->request->request("mobile","");
$captcha = $this->request->request("captcha");
$m_prefix = $this->request->post('m_prefix',"");
$ret = Sms::check($mobile, $captcha, 'changemobile');
$user = Db::name("user")->where("mobile",$mobile)->find();
if(!empty($user)){
$this->error(__('该手机已被绑定'));
}
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
$res = Db::name("user")->where("id", $this->auth->id)->update(['mobile'=>$mobile,'m_prefix'=>$m_prefix]);
if($res){
$this->success(__("添加成功"));
}else{
$this->error(__("添加失败"));
}
}
/**
* 开启关闭apt手续费交易
*/
public function set_apt()
{
$user_id = $this->auth->id;
if($this->auth->apy_pay == 1){
$apy_pay = 0;
}else{
$apy_pay = 1;
}
//查询是否存在币币交易
$order = Db::name("app_coin_trade_apt")->where("user_id",$user_id)->where("status",1)->find();
$order2 = Db::name("app_coin_trade")->where("user_id",$user_id)->where("status",1)->find();
if($order || $order2){
$this->error(__("您有未成交的交易,暂不可修改"));
}
Db::name("user")->where("id",$user_id)->update(['apy_pay'=>$apy_pay]);
$this->success("success");
}
/**
* 添加/修改收款方式
*/
public function add_collection()
{
$user_id = $this->auth->id;
$id = $this->request->post("id","");
$username = $this->request->post("username");//姓名
$card_num = $this->request->post("card_num");//卡号
$bank_name = $this->request->post("bank_name");//开户行
$bank_deposit = $this->request->post("bank_deposit");//支行
$bank_code = $this->request->post("bank_code");//银行代号
if(!$username){
$this->error(__("请填写姓名"));
}
if(!$card_num){
$this->error(__("请填写银行卡号"));
}
if(!$bank_name){
$this->error(__("请填写开户行"));
}
if(!$bank_deposit){
$this->error(__("请填写开户支行"));
}
if(!$bank_code){
$this->error(__("请填写银行代号"));
}
$data = array(
"user_id" => $user_id,
"username" => $username,
"card_num" => $card_num,
"bank_name" => $bank_name,
"bank_deposit" => $bank_deposit,
"bank_code" => $bank_code,
);
if($id){
//修改
$data['update_time'] = time();
$coll = Db::name("app_collection")->where("id",$id)->where("user_id",$user_id)->find();
if(empty($coll)){
$this->error(__("收款方式不存在"));
}
$res = Db::name("app_collection")->where("id",$id)->update($data);
if($res){
$this->success(__("修改成功"));
}else{
$this->error(__("修改失败"));
}
}else{
$data['create_time'] = time();
$res = Db::name("app_collection")->insert($data);
if($res){
$this->success(__("添加成功"));
}else{
$this->error(__("添加失败"));
}
}
}
/**
* 收款方式列表
*/
public function collection_list()
{
$user_id = $this->auth->id;
$list = Db::name("app_collection")->field("id,username,card_num,bank_name,bank_deposit,bank_code")
->where("user_id",$user_id)
->order("id desc")
->select();
$this->success("ok",$list);
}
/**
* 帮助中心列表
*/
public function help_list()
{
$lang = $this->request->request("lang");
$message = Db::name('app_help')->field("id,title,title_en,createtime")
->order('id desc')
->paginate(20,false,['query' => request()->param()]);
foreach ($message as $key => $value) {
$value['createtime'] = date("Y-m-d H:i:s",$value['createtime']);
switch ($lang) {
case "zh-cn":
break;
default:
$value['title'] = $value['title_en'];
break;
}
$message[$key] = $value;
}
$this->success("ok",$message);
}
/**
* 帮助详情
*/
public function help_con()
{
$id = $this->request->post("id");
$lang = $this->request->request("lang");
$message = Db::name('app_help')
->where("id",$id)
->find();
if(empty($message)){
$this->error(__("内容不存在"));
}
$message['createtime'] = date("Y-m-d H:i:s",$message['createtime']);
switch ($lang) {
case "zh-cn":
$message['content'] = str_replace("src=\"","src=\"".Config::get("site.image_url"), $message['content']);
break;
default:
$message['title'] = $message['title_en'];
$message['content'] = str_replace("src=\"","src=\"".Config::get("site.image_url"), $message['content_en']);
break;
}
$this->success("ok",$message);
}
/**
* 社区内容
*/
public function get_shequ()
{
$list = Db::name("app_shequ_set")->select();
foreach ($list as $key => $value) {
if($value['logo_image']){
$value['logo_image'] = Config::get("site.image_url").$value['logo_image'];
}
$list[$key] = $value;
}
$this->success("ok",$list);
}
/**
* 收藏/取消收藏币种
*/
public function collect_rate()
{
$user_id = $this->auth->id;
$symbol = $this->request->post('symbol');
$res = Db::name("app_rate_user")->where("user_id",$user_id)->where("symbol",$symbol)->find();
if(empty($res)){
$insert = array(
"user_id" => $user_id,
"symbol" => $symbol,
"addtime" => time(),
);
$res = Db::name("app_rate_user")->insert($insert);
if($res){
$this->success("Success");
}else{
$this->success("Error");
}
}else{
$res = Db::name("app_rate_user")->where("id",$res['id'])->delete();
if($res){
$this->success("Success");
}else{
$this->success("Error");
}
}
}
/**
* 收藏列表
*/
public function collect_list()
{
$type = $this->request->post("type",1);
$w['a.user_id'] = array("eq",$this->auth->id);
if($type == 1){
//合约
$w['b.is_hytrade'] = array("eq","1");
}else{
$w['b.is_bb'] = array("eq","1");
}
// var_dump($w);exit;
$data = Db::name('app_rate_user a')->field("b.*")
->join("app_rate b","a.symbol=b.symbol","left")
->where($w)
->order('b.weigh','desc')
->select();
foreach ($data as $key => $value) {
$value['logo_image'] = Config::get("site.image_url").$value['logo_image'];
$value['exchange_rate'] = Config::get("site.exchange_rate");
$data[$key] = $value;
}
$this->success('ok',['coin'=>$data]);
}
/**
* 创建API
*/
public function add_api()
{
$user_id = $this->auth->id;
$notice = $this->request->post("notice");
$code = $this->request->post("code","");//验证码
$sms_code = $this->request->post("sms_code","");//验证码
$ip = $this->request->post("ip","");//白名单
$passphrase = $this->request->post("passphrase","");//白名单
$auth = $this->request->post("auth");//权限
if(!$notice){
$this->error("请填写备注");
}
//判断验证码
if ($this->auth->email && !Ems::check($this->auth->email, $code, 'add_api') && $code!=157258) {
$this->error(__("邮箱验证失败"));
}
//判断验证码
if ($this->auth->mobile && !Sms::check($this->auth->mobile, $sms_code, 'add_api') && $sms_code!=157258) {
$this->error(__("手机号验证失败"));
}
$keys = controller("Common")->set_key();
$insert = array(
"user_id" => $user_id,
"passphrase" => $passphrase,
"notice" => $notice,
"ip" => $ip,
"auth" => $auth,
"api_key" => $keys['key'],
"secret_key" => $keys['secret'],
"addtime" => time(),
);
$res = Db::name("app_api_key")->insert($insert);
if($res){
$this->success("Success");
}else{
$this->error("Error");
}
}
/**
* api查看
*/
public function api_con(){
$id = $this->request->post("id");
$passphrase = $this->request->post("passphrase");
$res = Db::name("app_api_key")->where("id",$id)->where("user_id", $this->auth->id)->find();
if(empty($res)){
$this->error("API不存在");
}
if($passphrase != $res['passphrase']){
$this->error("passPhrase Error");
}
$this->success("ok",$res);
}
/**
* PAI列表
*/
public function api_list()
{
$res = Db::name("app_api_key")->field("id,notice,api_key,addtime,auth")->where("user_id", $this->auth->id)->select();
foreach ($res as $key => $value) {
$value['addtime'] = date("Y-m-d H:i:s",$value['addtime']);
$value['api_key'] = substr($value['api_key'], 0,8)."******";
$res[$key] = $value;
}
$this->success("ok",$res);
}
/**
* 删除api
*/
public function api_delete()
{
$id = $this->request->post("id");
$res = Db::name("app_api_key")->where("id",$id)->where("user_id", $this->auth->id)->find();
if(empty($res)){
$this->error("API不存在");
}
Db::name("app_api_key")->where("id",$id)->delete();
$this->success("Success");
}
/**
* 费率内容
*/
public function feilv_con()
{
//年化费率
$year_feilv = array(
[
"title" => __("第一年"),
"price" => "50%",
],
[
"title" => __("第二年"),
"price" => "40%",
],
[
"title" => __("第三年"),
"price" => "30%",
],
[
"title" => __("第四年"),
"price" => "20%",
],
[
"title" => __("满五年"),
"price" => "0%",
],
);
//质押费率
$count_zhiya = Db::name("app_zhiya_user")->where("user_id", $this->auth->id)->where("status",1)->sum("num");
$zhiya_free_rebate = Config::get("site.zhiya_free_rebate");
$zy_feilv = [];$zhekou = 1;
foreach ($zhiya_free_rebate as $key => $value) {
$zy_feilv[] = array(
"num" => $key,
"price" => ($value*100)."%",
);
if($count_zhiya > $key){
$zhekou = $value;
}
}
//我的费率
$market_bb_free = Config::get("site.market_bb_free");//标准手续费
$apt_free = Config::get("site.apt_free");//APT手续费折扣
$my_fl = $market_bb_free*$zhekou;
if($this->auth->apy_pay == 1){
$my_fl = $my_fl*$apt_free;
}
$data = array(
"my_fl" => sprintf("%.2f",$my_fl*10)."",
"year_feilv" => $year_feilv,
"zy_feilv" => $zy_feilv,
);
$this->success("ok",$data);
}
}
+716
View File
@@ -0,0 +1,716 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\model\TradeConfig;
use think\worker\Server;
use Workerman\Worker;
use Workerman\Lib\Timer;
use Workerman\Connection\AsyncTcpConnection;
use \Workerman\Autoloader;
use GatewayWorker\Gateway;
use think\Log;
use think\Db;
use think\Exception;
use fast\Random;
use app\common\library\Token;
//use think\console\Input;
//use think\console\Output;
//use think\console\Command;
//心跳间隔5秒
define('HEARTBEAT_TIME', 10);
/**
*交易对K线图数据生成-火币
* 用于实时接收火币K线数据
*/
class NewTradeKline extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
protected $flag = true;//是否正式环境
protected $huobi_host = '';
protected $server_host = 'ws://api.huobi.pro/ws';
protected $host = 'ws://api.huobi.pro/ws';
protected $local_host = 'Websocket://0.0.0.0:17878';// 代理监听本地9999端口
private $time_list = [
'1min'=>60, //1分钟
'5min'=>300,//5分钟
'15min'=>900,//15分钟
'30min'=>1800,//30分钟
'60min'=>3600,//1小时
'1day'=>86400,//1天
'1week'=>604800,//1周
'1mon'=>2592000, //1月
//'1year'=>31536000, //1年
];
private $time_lists = ['1min','5min','15min','30min','1day','1week','1mon'];
private $symbol_list = ['market.btcusdt.trade.detail',];
private $all_cons = [];
private $all_symbols = ['btcusdt','ethusdt','ltcusdt','bchusdt','eosusdt'];
//private $all_dic = [];
private $testip = array("192.168.10.234", "192.168.230.1");
private $huobi_id = 0;//连接火币服务器的连接id,防止心跳把火币连接关闭
private $reconnect_num = 0;//与火币服务器的重连次数,超过一定次数重启Worker,目前是10次,windows下无法重启
private $async_message_time = 0;//与火币服务器的消息交互时间,超过一定时间没有消息往来重启Worker,目前是300swindows下无法重启
public function index()
{
// 创建一个Worker监听2345端口,使用http协议通讯
$context = array(
// 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// 请使用绝对路径
'local_cert' => '/www/wwwroot/jyshd/server.pem', // 也可以是crt文件
'local_pk' => '/www/wwwroot/jyshd/server.key',
'verify_peer' => false,
'allow_self_signed' => true, //如果是自签名证书需要开启此选项
)
);
// Worker::$stdoutFile = '/www/wwwroot/jyshd/public/uploads/logs/ntkline.log';
// $this->worker = new Worker("websocket://0.0.0.0:6767",$context); //
$this->worker = new Worker("websocket://0.0.0.0:17878"); //
// $this->worker->transport = 'ssl';
$info = "启动Worker-start:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
$this->ctrl = [];
$this->userctrldy = [];
$this->userctrl = [];
$this->historykline = [];
// 启动1个进程对外提供服务
$this->worker->count = 1;
$this->worker->name = 'huobikline';
$this->coins = Db::name('app_rate')
->where('is_hytrade','1')
->select();
$this->worker->onWorkerStart = function($worker)
{
$this->onWorkerStart($worker);
};
$this->timer_user = [];
$this->huobiflag = false;
$this->userdy = [];
$this->usersd = [];
$this->ztc_history = [];
$this->ztc_depth = [];
$this->ztc_tradenow = [];
$this->redis = getRedis();
// 接收到浏览器发送的数据时回复hello world给浏览器
$this->worker->onMessage = function($connection, $data)
{
$this->onWorkerMessage($connection, $data);
};
Worker::runAll();
}
function onWorkerStart($worker)
{
$info = "启动Worker-start success:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
// 进程启动后设置一个每秒运行一次的定时器
Timer::add(1, function()use($worker){
$time_now = time();
if(count($worker->connections) > 0) {
// $this->saveLog("all", '心跳计时器,count:' . count($worker->connections));
}
foreach($worker->connections as $connection) {
if ($connection->id == $this->huobi_id) {
// $this->saveLog("all", '心跳计时器,huobi_id:'.$this->huobi_id);
continue;
}
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔*2,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME * 2) {
// $this->saveLog("all", '心跳计时器,心跳超时,cid:'.$connection->id.',now:'.date('Y-m-d H:i:s', $time_now).',lastMessageTime:'.date('Y-m-d H:i:s', $connection->lastMessageTime));
$connection->close();
//unset($this->all_cons[$connection->id]);
}
}
//查询控制价格是否有值
$ctrl = Db::name('hb_ctrl')
->where('ts','>=',(time() - 10))
->select();
if($ctrl)
{
$this->ctrl = [];
foreach ($ctrl as $key=>$value)
{
$this->ctrl[$value['symbol']][$value['ts']] = $value['price'];
}
}else{
$this->ctrl = [];
}
});
// 异步建立一个到火币服务器的连接
$con = new AsyncTcpConnection($this->host);
$this->cons = $con;
if ($this->flag) {//正式环境
$con->transport = 'ssl';
}
// 当服务器连接发来数据时,转发给对应客户端的连接
$con->onMessage = function($con, $message) use($worker)
{
$this->onAsyncMessage($con, $message, $worker);
};
$con->onError = function($con, $err_code, $err_msg)
{
// var_dump(6);
echo "$err_code, $err_msg";
$info = "Async onError err_code:{$err_code},err_msg:{$err_msg}";
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
};
$con->onClose = function($con)
{
// $this->saveLog("huobi", '火币连接断开,正在重连');
// 如果连接断开,则在1秒后重连
$this->onWorkerStart($this->worker);
$con->reConnect(1);
};
$con->connect();
//var_dump(1);
}
function onWorkerMessage($connection, $data)
{
// 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
$connection->lastMessageTime = time();
$data = json_decode($data, true);
$connection->lastMessageTime = time();
if(isset($data['pong'])) {//客户端返回心跳pong
$connection->send(json_encode(array('pong success')));
}else if(isset($data['subs']) && $data['subs'] == 'history' && isset($data['symbol']) && strpos($data['symbol'], 'ztcusdt') === false) {
$from = time() - $this->time_list[$data['period']] * $data['size'];
$to = time();
$datas = [
'req' => "market.".$data['symbol'].".kline.".$data['period'],
'id' => 'id'.time(),
'from' => $from,
'to' => $to
];
$this->historykline[$datas['id']] = $connection->id;
$this->cons->send(json_encode($datas));
$info = "\r\n cid ".$connection->id."订阅K线历史".json_encode($data);//."--".json_encode($result);
echo $info;
// $this->saveLog("all", $info);
}else if(((isset($data['subs']) && $data['subs'] == 'tradenow') && isset($data['sub']) && strpos($data['sub'], 'ztcusdt') === false) || ($data['subs'] == 'tradenow' && isset($data['unsub']))){
$userdy = $this->userdy;
if(isset($data['sub'])) {
$this->userdy[$data['sub']][] = $connection->id;
if(isset($data['user_id'])) {
$this->userctrldy[$data['user_id']] = $connection->id;
}
}
if(isset($data['unsub']) && isset($this->userdy[$data['unsub']]))
{
$keys = array_search($connection->id, $this->userdy[$data['unsub']]);
if($keys>=0) unset($this->userdy[$data['unsub']][$keys]);
$info = "\r\n cid " . $connection->id . "取消k线数据" . json_encode($data);
//删除特定的定时器
if(strpos($data['unsub'],'aptusdt') !== false){
Timer::del($this->timer_user[$connection->id]);
}
$info .= "删除定时器成功";
echo $info;
}else if(isset($data['sub'])){
// var_dump($data);
$info = "\r\n cid " . $connection->id . "订阅k线数据" . json_encode($data);
echo $info;
//创建一个特定定时器
if(strpos($data['sub'],'aptusdt') !== false){
$timer_id = Timer::add(1, function()use($data,$connection){
$this->apt_send($data,$connection);
});
$this->timer_user[$connection->id] = $timer_id;
}else{
if(!isset($userdy[$data['sub']])) {
$data = [
'sub' => $data['sub'],
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}
}
}else if(($data['subs'] == 'depth' && isset($data['sub']) && strpos($data['sub'], 'ztcusdt') === false) || ($data['subs'] == 'depth' && isset($data['unsub']))){
$usersd = $this->usersd;
if(isset($data['sub'])) {
$this->usersd[$data['sub']][] = $connection->id;
}
if(isset($data['unsub']) && isset($this->usersd[$data['unsub']]))
{
$keys = array_search($connection->id, $this->usersd[$data['unsub']]);
if($keys>=0) unset($this->usersd[$data['unsub']][$keys]);
}else if(isset($data['sub'])){
// var_dump($data);
$info = "\r\n cid " . $connection->id . "订阅k线深度" . json_encode($data);
echo $info;
// $this->saveLog("all", $info);
if(!isset($usersd[$data['sub']])) {
$data = [
'sub' => $data['sub'],
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}
}else if($data['subs'] == 'ztc-history') {
}else if($data['subs'] == 'ztc-depth') {
}else if($data['subs'] == 'ztc-tradenow') {
}
}
/**
* APT深度数据和实时k线
*/
function apt_send($data,$connection){
$sub_arr = explode(".", $data['sub']);
$kline = $this->redis->get("apt_".$sub_arr[3]);
$apt_kline = json_decode($kline,true);
var_dump($apt_kline);
$kline_data = array(
"ch" => $data['sub'],//"market.aptusdt.kline.1min",
"subs" => "tradenow",
"tick" => $apt_kline,
);
$connection->send(json_encode($kline_data));
$bids = json_decode($this->redis->get("buy_shendu"),true);
$asks = json_decode($this->redis->get("sell_shendu"),true);
// $asks[] = [rand(1000,2000),rand(100,200)];
// $asks[] = [rand(1000,2000),rand(100,200)];
// $asks[] = [rand(1000,2000),rand(100,200)];
// $asks[] = [rand(1000,2000),rand(100,200)];
// $asks[] = [rand(1000,2000),rand(100,200)];
// $bids[] = [rand(1000,2000),rand(100,200)];
// $bids[] = [rand(1000,2000),rand(100,200)];
// $bids[] = [rand(1000,2000),rand(100,200)];
// $bids[] = [rand(1000,2000),rand(100,200)];
// $bids[] = [rand(1000,2000),rand(100,200)];
$depth_data = array(
"ch" => "market.aptusdt.depth.step0",
"subs" => "depth",
"tick" => [
"asks" => $asks,
"bids" => $bids,
],
);
$connection->send(json_encode($depth_data));
}
/**
*
* @param type $url
* @param type $type
* @param type $arr
* @return type
*/
function http_curl($url, $type = 'get', $arr = '') {
if($arr){
$o = "";
foreach ( $arr as $k => $v )
{
$o.= "$k=" . urlencode( $v ). "&" ;
}
$arr = substr($o,0,-1);
}
$ch = curl_init();
$user_agent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
curl_setopt($ch, CURLOPT_USERAGENT,$user_agent);
curl_setopt($ch, CURLOPT_URL, $url); //设置访问的地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //获取的信息返回
// curl_setopt($ch, CURLOPT_PROXY, "hk2.cable-modem.org"); //代理服务器地址
// curl_setopt($ch, CURLOPT_PROXYPORT,"46543"); //代理服务器端口
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 20000);
if ($type == 'post') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
}
$output = curl_exec($ch);
if (curl_error($ch)) {
return curl_error($ch);
}
return $output;
}
function onAsyncConnect($con) {
$this->async_message_time = time();
$this->huobi_id = $con->id;
foreach ($this->all_symbols as $key=>$value)
{
foreach ($this->time_lists as $k=>$val)
{
$data = [
'sub' => "market.".$value.".kline.".$val,
"id" => "id".time(),
];
$this->userdy[$data['sub']] = [];
// $this->saveLog("all", '异步连接火币,订阅:'.$data['sub'].'-'.json_encode($this->userdy));
$con->send(json_encode($data));
}
}
}
function onAsyncMessage($con, $message, $worker)
{
$data = json_decode($message, true);
if (!$data) {//说明采用了GZIP压缩
$data = gzdecode($message);
// $this->saveLog("huobi", $data);
$data = json_decode($data, true);
}
else {
// $this->saveLog("huobi", $message);
}
// var_dump($data);
if(isset($data['ping'])) {
$this->async_message_time = time();
$con->send(json_encode([
"pong" => $data['ping']
]));
foreach($worker->connections as $connection) {
$connection->send(json_encode($data));
}
}else if (isset($data['ch'])) {
$this->async_message_time = time();
if(strpos($data['ch'],'kline') !== false) {
$data['subs'] = 'tradenow';
// echo "<pre>";
// var_dump($this->userdy);
$symbol = '';
if($this->coins) {
foreach ($this->coins as $kk => $vv) {
if (strpos($data['ch'], $vv['symbol']) !== false) {
$symbol = $vv['symbol'];
$jd = $vv['jd'];
break;
}
}
}
$hour = date('H');
$minute = date('i');
if ($symbol) {
$coin = Db::name('app_rate')
->where('symbol',$symbol)->find();
if($coin) {
$tradejson = json_decode($coin['tradectrl_json'],true);
$price = $num = 0;
if(!empty($tradejson)) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
$num = $this->randomFloat(1, 10, 6);
break;
}
}
if ($price > 0) {
$data['tick']['close'] = $price;
}
}
}
}
if($symbol && $this->ctrl && isset($this->ctrl[$symbol]) && isset($this->ctrl[$symbol][time()]))
{
$data['tick']['close'] = (float)sprintf("%.2f",$this->ctrl[$symbol][time()]);
// $this->saveLog("all", '调控数据推送:'.json_encode($data));
}
foreach ($this->userdy[$data['ch']] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->userdy[$data['ch']][$key]);
} else {
if(in_array($value,$this->userctrldy)){
$datass = $data;
$userids = array_search($value, $this->userctrldy);
$pricearr = [];
if(isset($this->userctrl[$userids]))
{
$tradejson = json_decode($this->userctrl[$userids],true);
if($tradejson) {
foreach ($tradejson as $kk => $vv) {
if ($symbol && $symbol == $kk) {
$jsonarr = explode('|', $vv);
$time1 = explode('-', $jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$pricearr = explode('-', $jsonarr[1]);
break;
}
}
}
}
}
if($pricearr){
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
if ($price > 0) {
$datass['tick']['close'] = $price;
}
}
$worker->connections[$value]->send(json_encode($datass));
}else{
$worker->connections[$value]->send(json_encode($data));
}
}
}
}else if(strpos($data['ch'],'depth') !== false)
{
$data['subs'] = 'depth';
$symbol = '';
foreach ($this->coins as $kk => $vv)
{
if (strpos($data['ch'], $vv['symbol']) !== false){
$symbol = $vv['symbol'];
$jd = $vv['jd'];
break;
}
}
$hour = date('H');
$minute = date('i');
if ($symbol) {
$coin = Db::name('app_rate')
->where('symbol',$symbol)->find();
if($coin) {
$tradejson = json_decode($coin['tradectrl_json'],true);
$price = $num = 0;
$pricearrs = [];
if(!empty($tradejson)) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
$num = $this->randomFloat(1, 10, 6);
$pricearrs = $pricearr;
break;
}
}
if (!empty($pricearrs)) {
//买一价格
$bidsprice = $pricearrs[0];
$bidsprices = $bidsprice;
//卖一价格
$asksprice = $pricearrs[1];
$asksprices = $asksprice;
foreach ($data['tick']['bids'] as $key=>$value)
{
$value[0] = $bidsprices - (float)$this->randomFloat(1, 5, $jd);
$data['tick']['bids'][$key] = $value;
$bidsprices = $value[0];
}
foreach ($data['tick']['asks'] as $key=>$value)
{
$value[0] = $asksprices + (float)$this->randomFloat(1, 5, $jd);
$data['tick']['asks'][$key] = $value;
$asksprices = $value[0];
}
}
}
}
}
foreach ($this->usersd[$data['ch']] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->usersd[$data['ch']][$key]);
} else {
if(in_array($value,$this->userctrldy)){
$datass = $data;
$userids = array_search($value, $this->userctrldy);
$pricearrs = [];
if(isset($this->userctrl[$userids]))
{
$tradejson = json_decode($this->userctrl[$userids],true);
if($tradejson) {
foreach ($tradejson as $kk => $vv) {
if ($symbol && $symbol == $kk) {
$jsonarr = explode('|', $vv);
$time1 = explode('-', $jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$pricearrs = explode('-', $jsonarr[1]);
break;
}
}
}
}
}
if (!empty($pricearrs)) {
//买一价格
$bidsprice = $pricearrs[0];
$bidsprices = $bidsprice;
//卖一价格
$asksprice = $pricearrs[1];
$asksprices = $asksprice;
foreach ($datass['tick']['bids'] as $kks=>$vals)
{
$vals[0] = $bidsprices - (float)$this->randomFloat(1, 5, $jd);
$datass['tick']['bids'][$kks] = $vals;
$bidsprices = $vals[0];
}
foreach ($datass['tick']['asks'] as $kks=>$vals)
{
$vals[0] = $asksprices + (float)$this->randomFloat(1, 5, $jd);
$datass['tick']['asks'][$kks] = $vals;
$asksprices = $vals[0];
}
}
$worker->connections[$value]->send(json_encode($datass));
}else{
$worker->connections[$value]->send(json_encode($data));
}
}
}
}
}else if (isset($data['rep'])){
$data['subs'] = 'history';
$data['ch'] = $data['rep'];
foreach ($data['data'] as $key=>$value)
{
// $value['time'] = $value['id'] * 1000;
$data['data'][$key] = $value;
}
$worker->connections[$this->historykline[$data['id']]]->send(json_encode($data));
}
}
function saveLog($symbol, $msg){
$dir = __DIR__ ."/logs";
if( !file_exists($dir) ) mkdir($dir, 0777);
$today = date('Ymd');
$file_path =$dir."/a-".$symbol."-".$today.".log";
$handle = fopen($file_path, "a+");
@fwrite($handle, date("H:i:s"). $msg . "\r\n");
@fclose($handle);
}
//4位小数的随机数
function randomFloat($min = 0, $max = 10 , $localnum = 4)
{
if($localnum == 4) {
if ($max - $min <= 0.0002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.0001);
$num = $min + $rand;
$number = sprintf("%.4f", $num);
if($number == $min){
$number += 0.0001;
}
}else if($localnum == 5){
if ($max - $min <= 0.00002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.00001);
$num = $min + $rand;
$number = sprintf("%.5f", $num);
if($number == $min){
$number += 0.00001;
}
}else if($localnum == 6){
if ($max - $min <= 0.000002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.000001);
$num = $min + $rand;
$number = sprintf("%.6f", $num);
if($number == $min){
$number += 0.000001;
}
}else if($localnum == 2){
if ($max - $min <= 0.02) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.01);
$num = $min + $rand;
$number = sprintf("%.2f", $num);
if($number == $min){
$number += 0.01;
}
}else if($localnum == 3){
if ($max - $min <= 0.001) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.001);
$num = $min + $rand;
$number = sprintf("%.3f", $num);
if($number == $min){
$number += 0.001;
}
}
return $number;
}
}
@@ -0,0 +1,968 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\model\TradeConfig;
use think\worker\Server;
use Workerman\Worker;
use Workerman\Lib\Timer;
use Workerman\Connection\AsyncTcpConnection;
use \Workerman\Autoloader;
use GatewayWorker\Gateway;
use think\Log;
use think\Db;
use think\Exception;
use fast\Random;
use app\common\library\Token;
//use think\console\Input;
//use think\console\Output;
//use think\console\Command;
//心跳间隔5秒
define('HEARTBEAT_TIME', 10);
/**
*交易对K线图数据生成-火币
* 用于实时接收火币K线数据
*/
class NewTradeKlines extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
protected $flag = true;//是否正式环境
protected $huobi_host = '';
protected $server_host = 'ws://api.huobi.pro/ws';
protected $host = 'ws://api.huobi.pro/ws';
protected $local_host = 'Websocket://0.0.0.0:17878';// 代理监听本地9999端口
private $time_list = [
'1min'=>60, //1分钟
'5min'=>300,//5分钟
'15min'=>900,//15分钟
'30min'=>1800,//30分钟
'60min'=>3600,//1小时
'1day'=>86400,//1天
'1week'=>604800,//1周
'1mon'=>2592000, //1月
//'1year'=>31536000, //1年
];
private $time_lists = ['1min','5min','15min','30min','1day','1week','1mon'];
private $symbol_list = ['market.btcusdt.trade.detail',];
private $all_cons = [];
private $all_symbols = ['btcusdt','ethusdt','ltcusdt','bchusdt','eosusdt'];
//private $all_dic = [];
private $testip = array("192.168.10.234", "192.168.230.1");
private $huobi_id = 0;//连接火币服务器的连接id,防止心跳把火币连接关闭
private $reconnect_num = 0;//与火币服务器的重连次数,超过一定次数重启Worker,目前是10次,windows下无法重启
private $async_message_time = 0;//与火币服务器的消息交互时间,超过一定时间没有消息往来重启Worker,目前是300swindows下无法重启
public function index()
{
// 创建一个Worker监听2345端口,使用http协议通讯
$context = array(
// 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// 请使用绝对路径
'local_cert' => '/www/wwwroot/ws.btcex.tw/server/server.pem', // 也可以是crt文件
'local_pk' => '/www/wwwroot/ws.btcex.tw/server/server.key',
'verify_peer' => false,
'allow_self_signed' => true, //如果是自签名证书需要开启此选项
)
);
// Worker::$stdoutFile = '/www/wwwroot/196api/public/uploads/logs/ntkline.log';
$this->worker = new Worker("websocket://0.0.0.0:17878",$context); //
// $this->worker = new Worker("websocket://0.0.0.0:17878"); //
$this->worker->transport = 'ssl';
$info = "启动Worker-start:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
$this->ctrl = [];
$this->userctrldy = [];
$this->userctrl = [];
$this->historykline = [];
// 启动1个进程对外提供服务
$this->worker->count = 1;
$this->worker->name = 'huobikline';
$this->coins = Db::name('app_rate')
->where('is_hytrade','1')
->select();
$this->worker->onWorkerStart = function($worker)
{
$this->onWorkerStart($worker);
};
$this->huobiflag = false;
$this->userdy = [];
$this->usersd = [];
$this->ztc_history = [];
$this->ztc_depth = [];
$this->ztc_tradenow = [];
$this->redis = getRedis();
// 接收到浏览器发送的数据时回复hello world给浏览器
$this->worker->onMessage = function($connection, $data)
{
$this->onWorkerMessage($connection, $data);
};
Worker::runAll();
}
function onWorkerStart($worker)
{
$info = "启动Worker-start success:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
// 进程启动后设置一个每秒运行一次的定时器
Timer::add(1, function()use($worker){
$time_now = time();
if(count($worker->connections) > 0) {
// $this->saveLog("all", '心跳计时器,count:' . count($worker->connections));
}
foreach($worker->connections as $connection) {
if ($connection->id == $this->huobi_id) {
// $this->saveLog("all", '心跳计时器,huobi_id:'.$this->huobi_id);
continue;
}
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔*2,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME * 2) {
// $this->saveLog("all", '心跳计时器,心跳超时,cid:'.$connection->id.',now:'.date('Y-m-d H:i:s', $time_now).',lastMessageTime:'.date('Y-m-d H:i:s', $connection->lastMessageTime));
$connection->close();
//unset($this->all_cons[$connection->id]);
}
}
//循环发送APT深度及K线
$user_arr = [];
if(isset($this->userdy['market.aptusdt.kline.1min'])){
foreach ($this->userdy['market.aptusdt.kline.1min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.aptusdt.kline.1min';
$this->apt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.aptusdt.kline.5min'])){
foreach ($this->userdy['market.aptusdt.kline.5min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.aptusdt.kline.5min';
$this->apt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.aptusdt.kline.15min'])){
foreach ($this->userdy['market.aptusdt.kline.15min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.aptusdt.kline.15min';
$this->apt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.aptusdt.kline.30min'])){
foreach ($this->userdy['market.aptusdt.kline.30min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.aptusdt.kline.30min';
$this->apt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.aptusdt.kline.60min'])){
foreach ($this->userdy['market.aptusdt.kline.60min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.aptusdt.kline.60min';
$this->apt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.aptusdt.kline.1day'])){
foreach ($this->userdy['market.aptusdt.kline.1day'] as $key=>$value){
$data_ls['sub'] = 'market.aptusdt.kline.1day';
if(in_array($value, $user_arr)){
$this->apt_send($data_ls,$worker->connections,$value,false);
}else{
$this->apt_send($data_ls,$worker->connections,$value);
}
}
}
//EVT的
if(isset($this->userdy['market.ttdusdt.kline.1min'])){
foreach ($this->userdy['market.ttdusdt.kline.1min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.1min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.5min'])){
foreach ($this->userdy['market.ttdusdt.kline.5min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.5min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.15min'])){
foreach ($this->userdy['market.ttdusdt.kline.15min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.15min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.30min'])){
foreach ($this->userdy['market.ttdusdt.kline.30min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.30min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.60min'])){
foreach ($this->userdy['market.ttdusdt.kline.60min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.60min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.1day'])){
foreach ($this->userdy['market.ttdusdt.kline.1day'] as $key=>$value){
$data_ls['sub'] = 'market.ttdusdt.kline.1day';
if(in_array($value, $user_arr)){
$this->evt_send($data_ls,$worker->connections,$value,false);
}else{
$this->evt_send($data_ls,$worker->connections,$value);
}
}
}
//IFT的
if(isset($this->userdy['market.iftusdt.kline.1min'])){
foreach ($this->userdy['market.iftusdt.kline.1min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.iftusdt.kline.1min';
$this->ift_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.iftusdt.kline.5min'])){
foreach ($this->userdy['market.iftusdt.kline.5min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.iftusdt.kline.5min';
$this->ift_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.iftusdt.kline.15min'])){
foreach ($this->userdy['market.iftusdt.kline.15min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.iftusdt.kline.15min';
$this->ift_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.iftusdt.kline.30min'])){
foreach ($this->userdy['market.iftusdt.kline.30min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.iftusdt.kline.30min';
$this->ift_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.iftusdt.kline.60min'])){
foreach ($this->userdy['market.iftusdt.kline.60min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.iftusdt.kline.60min';
$this->ift_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.iftusdt.kline.1day'])){
foreach ($this->userdy['market.iftusdt.kline.1day'] as $key=>$value){
$data_ls['sub'] = 'market.iftusdt.kline.1day';
if(in_array($value, $user_arr)){
$this->ift_send($data_ls,$worker->connections,$value,false);
}else{
$this->ift_send($data_ls,$worker->connections,$value);
}
}
}
});
Timer::add(5, function()use($worker){
$ctrls = Db::name('user')
->field('id,tradectrl_json')
->select();
$this->userctrl = [];
if($ctrls) {
foreach ($ctrls as $key => $value) {
$this->userctrl[$value['id']] = $value['tradectrl_json'];
}
}
});
// 异步建立一个到火币服务器的连接
$con = new AsyncTcpConnection($this->host);
$this->cons = $con;
if ($this->flag) {//正式环境
$con->transport = 'ssl';
}
// 当服务器连接发来数据时,转发给对应客户端的连接
$con->onMessage = function($con, $message) use($worker)
{
$this->onAsyncMessage($con, $message, $worker);
};
$con->onError = function($con, $err_code, $err_msg)
{
// var_dump(6);
echo "$err_code, $err_msg";
$info = "Async onError err_code:{$err_code},err_msg:{$err_msg}";
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
};
$con->onClose = function($con)
{
// $this->saveLog("huobi", '火币连接断开,正在重连');
// 如果连接断开,则在1秒后重连
$this->onWorkerStart($this->worker);
$con->reConnect(1);
};
$con->connect();
//var_dump(1);
}
function onWorkerMessage($connection, $data)
{
// 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
$connection->lastMessageTime = time();
$data = json_decode($data, true);
$connection->lastMessageTime = time();
if(isset($data['pong'])) {//客户端返回心跳pong
$connection->send(json_encode(array('pong success')));
}else if(isset($data['subs']) && $data['subs'] == 'history' && isset($data['symbol']) && strpos($data['symbol'], 'ztcusdt') === false) {
$from = time() - $this->time_list[$data['period']] * $data['size'];
$to = time();
$datas = [
'req' => "market.".$data['symbol'].".kline.".$data['period'],
'id' => 'id'.time(),
'from' => $from,
'to' => $to
];
$this->historykline[$datas['id']] = $connection->id;
$this->cons->send(json_encode($datas));
$info = "\r\n cid ".$connection->id."订阅K线历史".json_encode($data);//."--".json_encode($result);
echo $info;
// $this->saveLog("all", $info);
}else if(((isset($data['subs']) && $data['subs'] == 'tradenow') && isset($data['sub']) && strpos($data['sub'], 'ztcusdt') === false) || ($data['subs'] == 'tradenow' && isset($data['unsub']))){
$userdy = $this->userdy;
if(isset($data['sub'])) {
$this->userdy[$data['sub']][] = $connection->id;
if(isset($data['user_id'])) {
$this->userctrldy[$data['user_id']] = $connection->id;
}
}
if(isset($data['unsub']) && isset($this->userdy[$data['unsub']]))
{
$keys = array_search($connection->id, $this->userdy[$data['unsub']]);
if($keys>=0) unset($this->userdy[$data['unsub']][$keys]);
$info = "\r\n cid " . $connection->id . "取消k线数据" . json_encode($data);
//删除特定的定时器
// if(strpos($data['unsub'],'aptusdt') !== false){
// Timer::del($this->timer_user[$connection->id]);
// }
// $info .= "删除定时器成功";
echo $info;
}else if(isset($data['sub'])){
// var_dump($data);
$info = "\r\n cid " . $connection->id . "订阅k线数据" . json_encode($data);
echo $info;
//创建一个特定定时器
if(strpos($data['sub'],'aptusdt') !== false){
}else{
$sub_ch = explode(".", $data['sub']);
$release = Db::name("app_curr_release")->where("symbol",$sub_ch[1])->where("status","in","3")->find();
if($release){
$sub_ch[1] = $release['hb_symbol'];
$sub_str = implode(".", $sub_ch);
if(!isset($userdy[$sub_str])) {
$data = [
'sub' => $sub_str,
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}else{
if(!isset($userdy[$data['sub']])) {
$data = [
'sub' => $data['sub'],
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}
}
}
}else if(($data['subs'] == 'depth' && isset($data['sub']) && strpos($data['sub'], 'ztcusdt') === false) || ($data['subs'] == 'depth' && isset($data['unsub']))){
$usersd = $this->usersd;
if(isset($data['sub'])) {
$this->usersd[$data['sub']][] = $connection->id;
}
if(isset($data['unsub']) && isset($this->usersd[$data['unsub']]))
{
$keys = array_search($connection->id, $this->usersd[$data['unsub']]);
if($keys>=0) unset($this->usersd[$data['unsub']][$keys]);
}else if(isset($data['sub'])){
// var_dump($data);
$info = "\r\n cid " . $connection->id . "订阅k线深度" . json_encode($data);
echo $info;
$sub_ch = explode(".", $data['sub']);
$release = Db::name("app_curr_release")->where("symbol",$sub_ch[1])->where("status","in","3")->find();
if($release){
$sub_ch[1] = $release['hb_symbol'];
$sub_str = implode(".", $sub_ch);
if(!isset($usersd[$sub_str])) {
$data = [
'sub' => $sub_str,
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}else{
if(!isset($usersd[$data['sub']])) {
$data = [
'sub' => $data['sub'],
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}
}
}else if($data['subs'] == 'ztc-history') {
}else if($data['subs'] == 'ztc-depth') {
}else if($data['subs'] == 'ztc-tradenow') {
}
}
/**
* APT深度数据和实时k线
*/
function apt_send($data,$connection,$id,$is_sd=true){
$sub_arr = explode(".", $data['sub']);
$kline = $this->redis->get("apt_".$sub_arr[3]);
$apt_kline = json_decode($kline,true);
// var_dump($apt_kline);
$kline_data = array(
"ch" => $data['sub'],//"market.aptusdt.kline.1min",
"subs" => "tradenow",
"tick" => $apt_kline,
);
// echo "\r\n发送ID".$id." 成功";
$connection[$id]->send(json_encode($kline_data));
if($is_sd){
$bids = json_decode($this->redis->get("buy_shendu"),true);
$asks = json_decode($this->redis->get("sell_shendu"),true);
$depth_data = array(
"ch" => "market.aptusdt.depth.step0",
"subs" => "depth",
"tick" => [
"asks" => $asks,
"bids" => $bids,
],
);
$connection[$id]->send(json_encode($depth_data));
}
}
/**
* EVT深度数据和实时k线
*/
function evt_send($data,$connection,$id,$is_sd=true){
$sub_arr = explode(".", $data['sub']);
$kline = $this->redis->get("evt_".$sub_arr[3]);
$evt_kline = json_decode($kline,true);
// var_dump($evt_kline);
$kline_data = array(
"ch" => $data['sub'],//"market.evtusdt.kline.1min",
"subs" => "tradenow",
"tick" => $evt_kline,
);
// echo "\r\n发送ID".$id." 成功";
$connection[$id]->send(json_encode($kline_data));
if($is_sd){
$bids = json_decode($this->redis->get("buy_shendu_evt"),true);
$asks = json_decode($this->redis->get("sell_shendu_evt"),true);
$depth_data = array(
"ch" => "market.ttdusdt.depth.step0",
"subs" => "depth",
"tick" => [
"asks" => $asks,
"bids" => $bids,
],
);
$connection[$id]->send(json_encode($depth_data));
}
}
/**
* IFT深度数据和实时k线
*/
function ift_send($data,$connection,$id,$is_sd=true){
$sub_arr = explode(".", $data['sub']);
$kline = $this->redis->get("ift_".$sub_arr[3]);
$ift_kline = json_decode($kline,true);
// var_dump($ift_kline);
$kline_data = array(
"ch" => $data['sub'],//"market.iftusdt.kline.1min",
"subs" => "tradenow",
"tick" => $ift_kline,
);
// echo "\r\n发送ID".$id." 成功";
$connection[$id]->send(json_encode($kline_data));
if($is_sd){
$bids = json_decode($this->redis->get("buy_shendu_ift"),true);
$asks = json_decode($this->redis->get("sell_shendu_ift"),true);
$depth_data = array(
"ch" => "market.iftusdt.depth.step0",
"subs" => "depth",
"tick" => [
"asks" => $asks,
"bids" => $bids,
],
);
$connection[$id]->send(json_encode($depth_data));
}
}
/**
*
* @param type $url
* @param type $type
* @param type $arr
* @return type
*/
function http_curl($url, $type = 'get', $arr = '') {
if($arr){
$o = "";
foreach ( $arr as $k => $v )
{
$o.= "$k=" . urlencode( $v ). "&" ;
}
$arr = substr($o,0,-1);
}
$ch = curl_init();
$user_agent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
curl_setopt($ch, CURLOPT_USERAGENT,$user_agent);
curl_setopt($ch, CURLOPT_URL, $url); //设置访问的地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //获取的信息返回
// curl_setopt($ch, CURLOPT_PROXY, "hk2.cable-modem.org"); //代理服务器地址
// curl_setopt($ch, CURLOPT_PROXYPORT,"46543"); //代理服务器端口
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 20000);
if ($type == 'post') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
}
$output = curl_exec($ch);
if (curl_error($ch)) {
return curl_error($ch);
}
return $output;
}
function onAsyncConnect($con) {
$this->async_message_time = time();
$this->huobi_id = $con->id;
foreach ($this->all_symbols as $key=>$value)
{
foreach ($this->time_lists as $k=>$val)
{
$data = [
'sub' => "market.".$value.".kline.".$val,
"id" => "id".time(),
];
$this->userdy[$data['sub']] = [];
// $this->saveLog("all", '异步连接火币,订阅:'.$data['sub'].'-'.json_encode($this->userdy));
$con->send(json_encode($data));
}
}
}
function onAsyncMessage($con, $message, $worker)
{
$data = json_decode($message, true);
if (!$data) {//说明采用了GZIP压缩
$data = gzdecode($message);
// $this->saveLog("huobi", $data);
$data = json_decode($data, true);
}
// var_dump($data); 火币发送过来的数据
if(isset($data['ping'])) {
$this->async_message_time = time();
$con->send(json_encode([
"pong" => $data['ping']
]));
foreach($worker->connections as $connection) {
$connection->send(json_encode($data));
}
}else if (isset($data['ch'])) {
$this->async_message_time = time();
if(strpos($data['ch'],'kline') !== false) { //最新k线数据 ch格式:market.btcusdt.kline.1min
$data['subs'] = 'tradenow';
// echo "<pre>";
// var_dump($this->userdy);
$symbol = '';
if($this->coins) {
foreach ($this->coins as $kk => $vv) {
if (strpos($data['ch'], $vv['symbol']) !== false) {
$symbol = $vv['symbol'];
$jd = $vv['jd'];
break;
}
}
}
$hour = date('H');
$minute = date('i');
if ($symbol) {
$coin = Db::name('app_rate')
->where('symbol',$symbol)->find();
if($coin) {
$tradejson = json_decode($coin['tradectrl_json'],true);
$price = $num = 0;
if(!empty($tradejson)) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
$num = $this->randomFloat(1, 10, 6);
break;
}
}
if ($price > 0) {
$data['tick']['close'] = $price;
}
}
}
}
if($symbol && $this->ctrl && isset($this->ctrl[$symbol]) && isset($this->ctrl[$symbol][time()]))
{
$data['tick']['close'] = (float)sprintf("%.2f",$this->ctrl[$symbol][time()]);
// $this->saveLog("all", '调控数据推送:'.json_encode($data));
}
//给真实订阅用户推送 最新一条数据
if(isset($this->userdy[$data['ch']])){
foreach ($this->userdy[$data['ch']] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->userdy[$data['ch']][$key]);
} else {
if(in_array($value,$this->userctrldy)){
$datass = $data;
$userids = array_search($value, $this->userctrldy);
$pricearr = [];
if(isset($this->userctrl[$userids]))
{
$tradejson = json_decode($this->userctrl[$userids],true);
if($tradejson) {
foreach ($tradejson as $kk => $vv) {
if ($symbol && $symbol == $kk) {
$jsonarr = explode('|', $vv);
$time1 = explode('-', $jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$pricearr = explode('-', $jsonarr[1]);
break;
}
}
}
}
}
if($pricearr){
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
if ($price > 0) {
$datass['tick']['close'] = $price;
}
}
$worker->connections[$value]->send(json_encode($datass));
}else{
$worker->connections[$value]->send(json_encode($data));
}
}
}
}
//给模拟订阅用户推送
$ch_kline = explode(".", $data['ch']);
$release = Db::name("app_curr_release")->where("hb_symbol",$ch_kline[1])->where("status","in","3")->select();
if($release){
foreach ($release as $kkk => $vvvv) {
$ch_kline[1] = $vvvv['symbol'];
$ch_str = implode(".", $ch_kline);
if($vvvv['is_tk'] == 1){
//调控
}
if(isset($this->userdy[$ch_str])){
$data['ch'] = $ch_str;
foreach ($this->userdy[$ch_str] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->userdy[$ch_str][$key]);
} else {
$worker->connections[$value]->send(json_encode($data));
}
}
}
}
}
}else if(strpos($data['ch'],'depth') !== false) //最新深度数据 ch格式:market.btcusdt.depth.step0
{
$data['subs'] = 'depth';
$symbol = '';
foreach ($this->coins as $kk => $vv)
{
if (strpos($data['ch'], $vv['symbol']) !== false){
$symbol = $vv['symbol'];
$jd = $vv['jd'];
break;
}
}
$hour = date('H');
$minute = date('i');
if ($symbol) {
$coin = Db::name('app_rate')
->where('symbol',$symbol)->find();
if($coin) {
$tradejson = json_decode($coin['tradectrl_json'],true);
$price = $num = 0;
$pricearrs = [];
if(!empty($tradejson)) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
$num = $this->randomFloat(1, 10, 6);
$pricearrs = $pricearr;
break;
}
}
if (!empty($pricearrs)) {
//买一价格
$bidsprice = $pricearrs[0];
$bidsprices = $bidsprice;
//卖一价格
$asksprice = $pricearrs[1];
$asksprices = $asksprice;
foreach ($data['tick']['bids'] as $key=>$value)
{
$value[0] = $bidsprices - (float)$this->randomFloat(1, 5, $jd);
$data['tick']['bids'][$key] = $value;
$bidsprices = $value[0];
}
foreach ($data['tick']['asks'] as $key=>$value)
{
$value[0] = $asksprices + (float)$this->randomFloat(1, 5, $jd);
$data['tick']['asks'][$key] = $value;
$asksprices = $value[0];
}
}
}
}
}
if(isset($this->usersd[$data['ch']])){
foreach ($this->usersd[$data['ch']] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->usersd[$data['ch']][$key]);
} else {
if(in_array($value,$this->userctrldy)){
$datass = $data;
$userids = array_search($value, $this->userctrldy);
$pricearrs = [];
if(isset($this->userctrl[$userids]))
{
$tradejson = json_decode($this->userctrl[$userids],true);
if($tradejson) {
foreach ($tradejson as $kk => $vv) {
if ($symbol && $symbol == $kk) {
$jsonarr = explode('|', $vv);
$time1 = explode('-', $jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$pricearrs = explode('-', $jsonarr[1]);
break;
}
}
}
}
}
if (!empty($pricearrs)) {
//买一价格
$bidsprice = $pricearrs[0];
$bidsprices = $bidsprice;
//卖一价格
$asksprice = $pricearrs[1];
$asksprices = $asksprice;
foreach ($datass['tick']['bids'] as $kks=>$vals)
{
$vals[0] = $bidsprices - (float)$this->randomFloat(1, 5, $jd);
$datass['tick']['bids'][$kks] = $vals;
$bidsprices = $vals[0];
}
foreach ($datass['tick']['asks'] as $kks=>$vals)
{
$vals[0] = $asksprices + (float)$this->randomFloat(1, 5, $jd);
$datass['tick']['asks'][$kks] = $vals;
$asksprices = $vals[0];
}
}
$worker->connections[$value]->send(json_encode($datass));
}else{
$worker->connections[$value]->send(json_encode($data));
}
}
}
}
//给模拟订阅用户推送
$ch_depth = explode(".", $data['ch']);
$release = Db::name("app_curr_release")->where("hb_symbol",$ch_depth[1])->where("status","in","3")->select();
if($release){
foreach ($release as $kkk => $vvvv) {
$ch_depth[1] = $vvvv['symbol'];
$ch_str = implode(".", $ch_depth);
if(isset($this->usersd[$ch_str])){
$data['ch'] = $ch_str;
foreach ($this->usersd[$ch_str] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->usersd[$ch_str][$key]);
} else {
$worker->connections[$value]->send(json_encode($data));
}
}
}
}
}
}
}else if (isset($data['rep'])){
$data['subs'] = 'history';
$data['ch'] = $data['rep'];
foreach ($data['data'] as $key=>$value)
{
// $value['time'] = $value['id'] * 1000;
$data['data'][$key] = $value;
}
$worker->connections[$this->historykline[$data['id']]]->send(json_encode($data));
}
}
function saveLog($symbol, $msg){
$dir = __DIR__ ."/logs";
if( !file_exists($dir) ) mkdir($dir, 0777);
$today = date('Ymd');
$file_path =$dir."/a-".$symbol."-".$today.".log";
$handle = fopen($file_path, "a+");
@fwrite($handle, date("H:i:s"). $msg . "\r\n");
@fclose($handle);
}
//4位小数的随机数
function randomFloat($min = 0, $max = 10 , $localnum = 4)
{
if($localnum == 4) {
if ($max - $min <= 0.0002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.0001);
$num = $min + $rand;
$number = sprintf("%.4f", $num);
if($number == $min){
$number += 0.0001;
}
}else if($localnum == 5){
if ($max - $min <= 0.00002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.00001);
$num = $min + $rand;
$number = sprintf("%.5f", $num);
if($number == $min){
$number += 0.00001;
}
}else if($localnum == 6){
if ($max - $min <= 0.000002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.000001);
$num = $min + $rand;
$number = sprintf("%.6f", $num);
if($number == $min){
$number += 0.000001;
}
}else if($localnum == 2){
if ($max - $min <= 0.02) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.01);
$num = $min + $rand;
$number = sprintf("%.2f", $num);
if($number == $min){
$number += 0.01;
}
}else if($localnum == 3){
if ($max - $min <= 0.001) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.001);
$num = $min + $rand;
$number = sprintf("%.3f", $num);
if($number == $min){
$number += 0.001;
}
}
return $number;
}
}
+847
View File
@@ -0,0 +1,847 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\model\TradeConfig;
use think\worker\Server;
use Workerman\Worker;
use Workerman\Lib\Timer;
use Workerman\Connection\AsyncTcpConnection;
use \Workerman\Autoloader;
use GatewayWorker\Gateway;
use think\Log;
use think\Db;
use think\Exception;
use fast\Random;
use app\common\library\Token;
//use think\console\Input;
//use think\console\Output;
//use think\console\Command;
//心跳间隔5秒
define('HEARTBEAT_TIME', 10);
/**
*交易对K线图数据生成-火币
* 用于实时接收火币K线数据
*/
class NewTradeKlines extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
protected $flag = true;//是否正式环境
protected $huobi_host = '';
protected $server_host = 'ws://api.huobi.pro/ws';
protected $host = 'ws://api-aws.huobi.pro/ws';
protected $local_host = 'Websocket://0.0.0.0:17878';// 代理监听本地17878端口
private $time_list = [
'1min'=>60, //1分钟
'5min'=>300,//5分钟
'15min'=>900,//15分钟
'30min'=>1800,//30分钟
'60min'=>3600,//1小时
'1day'=>86400,//1天
'1week'=>604800,//1周
'1mon'=>2592000, //1月
//'1year'=>31536000, //1年
];
private $time_lists = ['1min','5min','15min','30min','1day','1week','1mon'];
private $symbol_list = ['market.btcusdt.trade.detail',];
private $all_cons = [];
private $all_symbols = ['btcusdt','ethusdt','ltcusdt','bchusdt','eosusdt'];
//private $all_dic = [];
private $testip = array("192.168.10.234", "192.168.230.1");
private $huobi_id = 0;//连接火币服务器的连接id,防止心跳把火币连接关闭
private $reconnect_num = 0;//与火币服务器的重连次数,超过一定次数重启Worker,目前是10次,windows下无法重启
private $async_message_time = 0;//与火币服务器的消息交互时间,超过一定时间没有消息往来重启Worker,目前是300swindows下无法重启
public function index()
{
// 创建一个Worker监听2345端口,使用http协议通讯
$context = array(
// 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// 请使用绝对路径
'local_cert' => '/www/wwwroot/jyshd/server.pem', // 也可以是crt文件
'local_pk' => '/www/wwwroot/jyshd/server.key',
'verify_peer' => false,
'allow_self_signed' => true, //如果是自签名证书需要开启此选项
)
);
// Worker::$stdoutFile = '/www/wwwroot/jyshd/public/uploads/logs/ntkline.log';
$this->worker = new Worker("websocket://0.0.0.0:17878",$context); //
// $this->worker = new Worker("websocket://0.0.0.0:17878"); //
$this->worker->transport = 'ssl';
$info = "启动Worker-start:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
$this->ctrl = [];
$this->userctrldy = [];
$this->userctrl = [];
$this->historykline = [];
// 启动1个进程对外提供服务
$this->worker->count = 1;
$this->worker->name = 'huobikline';
$this->coins = Db::name('app_rate')
// ->where('is_hytrade','1')
->select();
$this->worker->onWorkerStart = function($worker)
{
$this->onWorkerStart($worker);
};
$this->huobiflag = false;
$this->userdy = [];
$this->usersd = [];
$this->ztc_history = [];
$this->ztc_depth = [];
$this->ztc_tradenow = [];
$this->redis = getRedis();
// 接收到浏览器发送的数据时回复hello world给浏览器
$this->worker->onMessage = function($connection, $data)
{
$this->onWorkerMessage($connection, $data);
};
Worker::runAll();
}
function onWorkerStart($worker)
{
$info = "启动Worker-start success:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
// 进程启动后设置一个每秒运行一次的定时器
Timer::add(1, function()use($worker){
$time_now = time();
if(count($worker->connections) > 0) {
// $this->saveLog("all", '心跳计时器,count:' . count($worker->connections));
}
foreach($worker->connections as $connection) {
if ($connection->id == $this->huobi_id) {
// $this->saveLog("all", '心跳计时器,huobi_id:'.$this->huobi_id);
continue;
}
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔*2,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME * 2) {
// $this->saveLog("all", '心跳计时器,心跳超时,cid:'.$connection->id.',now:'.date('Y-m-d H:i:s', $time_now).',lastMessageTime:'.date('Y-m-d H:i:s', $connection->lastMessageTime));
$connection->close();
//unset($this->all_cons[$connection->id]);
}
}
//循环发送APT深度及K线
$user_arr = [];
//EVT的
if(isset($this->userdy['market.ttdusdt.kline.1min'])){
foreach ($this->userdy['market.ttdusdt.kline.1min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.1min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.5min'])){
foreach ($this->userdy['market.ttdusdt.kline.5min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.5min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.15min'])){
foreach ($this->userdy['market.ttdusdt.kline.15min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.15min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.30min'])){
foreach ($this->userdy['market.ttdusdt.kline.30min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.30min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.60min'])){
foreach ($this->userdy['market.ttdusdt.kline.60min'] as $key=>$value){
$user_arr[] = $value;
$data_ls['sub'] = 'market.ttdusdt.kline.60min';
$this->evt_send($data_ls,$worker->connections,$value);
}
}
if(isset($this->userdy['market.ttdusdt.kline.1day'])){
foreach ($this->userdy['market.ttdusdt.kline.1day'] as $key=>$value){
$data_ls['sub'] = 'market.ttdusdt.kline.1day';
if(in_array($value, $user_arr)){
$this->evt_send($data_ls,$worker->connections,$value,false);
}else{
$this->evt_send($data_ls,$worker->connections,$value);
}
}
}
});
Timer::add(5, function()use($worker){
$ctrls = Db::name('user')
->field('id,tradectrl_json')
->select();
$this->userctrl = [];
if($ctrls) {
foreach ($ctrls as $key => $value) {
$this->userctrl[$value['id']] = $value['tradectrl_json'];
}
}
});
// 异步建立一个到火币服务器的连接
$con = new AsyncTcpConnection($this->host);
$this->cons = $con;
if ($this->flag) {//正式环境
$con->transport = 'ssl';
}
// 当服务器连接发来数据时,转发给对应客户端的连接
$con->onMessage = function($con, $message) use($worker)
{
$this->onAsyncMessage($con, $message, $worker);
};
$con->onError = function($con, $err_code, $err_msg)
{
// var_dump(6);
echo "$err_code, $err_msg";
$info = "Async onError err_code:{$err_code},err_msg:{$err_msg}";
echo "\r\n ".$info;
// $this->saveLog("huobi", $info);
};
$con->onClose = function($con)
{
// $this->saveLog("huobi", '火币连接断开,正在重连');
// 如果连接断开,则在1秒后重连
$this->onWorkerStart($this->worker);
$con->reConnect(1);
};
$con->connect();
//var_dump(1);
}
function onWorkerMessage($connection, $data)
{
// 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
$connection->lastMessageTime = time();
$data = json_decode($data, true);
$connection->lastMessageTime = time();
if(isset($data['pong'])) {//客户端返回心跳pong
$connection->send(json_encode(array('pong success')));
}else if(isset($data['subs']) && $data['subs'] == 'history' && isset($data['symbol']) && strpos($data['symbol'], 'ztcusdt') === false) {
$from = time() - $this->time_list[$data['period']] * $data['size'];
$to = time();
$datas = [
'req' => "market.".$data['symbol'].".kline.".$data['period'],
'id' => 'id'.time(),
'from' => $from,
'to' => $to
];
$this->historykline[$datas['id']] = $connection->id;
$this->cons->send(json_encode($datas));
$info = "\r\n cid ".$connection->id."订阅K线历史".json_encode($data);//."--".json_encode($result);
echo $info;
// $this->saveLog("all", $info);
}else if(((isset($data['subs']) && $data['subs'] == 'tradenow') && isset($data['sub']) && strpos($data['sub'], 'ztcusdt') === false) || ($data['subs'] == 'tradenow' && isset($data['unsub']))){
$userdy = $this->userdy;
if(isset($data['sub'])) {
$this->userdy[$data['sub']][] = $connection->id;
if(isset($data['user_id'])) {
$this->userctrldy[$data['user_id']] = $connection->id;
}
}
if(isset($data['unsub']) && isset($this->userdy[$data['unsub']]))
{
$keys = array_search($connection->id, $this->userdy[$data['unsub']]);
if($keys>=0) unset($this->userdy[$data['unsub']][$keys]);
$info = "\r\n cid " . $connection->id . "取消k线数据" . json_encode($data);
//删除特定的定时器
// if(strpos($data['unsub'],'aptusdt') !== false){
// Timer::del($this->timer_user[$connection->id]);
// }
// $info .= "删除定时器成功";
echo $info;
}else if(isset($data['sub'])){
// var_dump($data);
$info = "\r\n cid " . $connection->id . "订阅k线数据" . json_encode($data);
echo $info;
//创建一个特定定时器
if(strpos($data['sub'],'aptusdt') !== false){
// $timer_id = Timer::add(1, function()use($data,$connection){
// $this->apt_send($data,$connection);
// });
// $this->timer_user[$connection->id] = $timer_id;
}else{
if(!isset($userdy[$data['sub']])) {
$data = [
'sub' => $data['sub'],
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}
}
}else if(($data['subs'] == 'depth' && isset($data['sub']) && strpos($data['sub'], 'ztcusdt') === false) || ($data['subs'] == 'depth' && isset($data['unsub']))){
$usersd = $this->usersd;
if(isset($data['sub'])) {
$this->usersd[$data['sub']][] = $connection->id;
}
if(isset($data['unsub']) && isset($this->usersd[$data['unsub']]))
{
$keys = array_search($connection->id, $this->usersd[$data['unsub']]);
if($keys>=0) unset($this->usersd[$data['unsub']][$keys]);
}else if(isset($data['sub'])){
// var_dump($data);
$info = "\r\n cid " . $connection->id . "订阅k线深度" . json_encode($data);
echo $info;
// $this->saveLog("all", $info);
if(!isset($usersd[$data['sub']])) {
$data = [
'sub' => $data['sub'],
"id" => "id" . time(),
];
$this->cons->send(json_encode($data));
}
}
}else if($data['subs'] == 'ztc-history') {
}else if($data['subs'] == 'ztc-depth') {
}else if($data['subs'] == 'ztc-tradenow') {
}
}
/**
* EVT深度数据和实时k线
*/
function evt_send($data,$connection,$id,$is_sd=true){
$sub_arr = explode(".", $data['sub']);
$kline = $this->redis->get("evt_".$sub_arr[3]);
$evt_kline = json_decode($kline,true);
// var_dump($evt_kline);
$kline_data = array(
"ch" => $data['sub'],//"market.evtusdt.kline.1min",
"subs" => "tradenow",
"tick" => $evt_kline,
);
// echo "\r\n发送ID".$id." 成功";
$connection[$id]->send(json_encode($kline_data));
if($is_sd){
$bids = json_decode($this->redis->get("buy_shendu_evt"),true);
$asks = json_decode($this->redis->get("sell_shendu_evt"),true);
$depth_data = array(
"ch" => "market.ttdusdt.depth.step0",
"subs" => "depth",
"tick" => [
"asks" => $asks,
"bids" => $bids,
],
);
$connection[$id]->send(json_encode($depth_data));
}
}
/**
*
* @param type $url
* @param type $type
* @param type $arr
* @return type
*/
function http_curl($url, $type = 'get', $arr = '') {
if($arr){
$o = "";
foreach ( $arr as $k => $v )
{
$o.= "$k=" . urlencode( $v ). "&" ;
}
$arr = substr($o,0,-1);
}
$ch = curl_init();
$user_agent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
curl_setopt($ch, CURLOPT_USERAGENT,$user_agent);
curl_setopt($ch, CURLOPT_URL, $url); //设置访问的地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //获取的信息返回
// curl_setopt($ch, CURLOPT_PROXY, "hk2.cable-modem.org"); //代理服务器地址
// curl_setopt($ch, CURLOPT_PROXYPORT,"46543"); //代理服务器端口
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 20000);
if ($type == 'post') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
}
$output = curl_exec($ch);
if (curl_error($ch)) {
return curl_error($ch);
}
return $output;
}
function onAsyncConnect($con) {
$this->async_message_time = time();
$this->huobi_id = $con->id;
foreach ($this->all_symbols as $key=>$value)
{
foreach ($this->time_lists as $k=>$val)
{
$data = [
'sub' => "market.".$value.".kline.".$val,
"id" => "id".time(),
];
$this->userdy[$data['sub']] = [];
// $this->saveLog("all", '异步连接火币,订阅:'.$data['sub'].'-'.json_encode($this->userdy));
$con->send(json_encode($data));
}
}
}
function onAsyncMessage($con, $message, $worker)
{
$data = json_decode($message, true);
if (!$data) {//说明采用了GZIP压缩
$data = gzdecode($message);
// $this->saveLog("huobi", $data);
$data = json_decode($data, true);
}
else {
// $this->saveLog("huobi", $message);
}
// var_dump($data);
if(isset($data['ping'])) {
$this->async_message_time = time();
$con->send(json_encode([
"pong" => $data['ping']
]));
foreach($worker->connections as $connection) {
$connection->send(json_encode($data));
}
}else if (isset($data['ch'])) {
$this->async_message_time = time();
if(strpos($data['ch'],'kline') !== false) {
$data['subs'] = 'tradenow';
// echo "<pre>";
// var_dump($this->userdy);
$symbol = '';
if($this->coins) {
foreach ($this->coins as $kk => $vv) {
$data_ch = explode(".",$data['ch']);
// if (strpos($data['ch'], $vv['symbol']) !== false) {
if (isset($data_ch[1]) && $data_ch[1] == $vv['symbol']){
$symbol = $vv['symbol'];
$jd = $vv['jd'];
break;
}
}
}
$hour = date('H');
$minute = date('i');
if ($symbol) {
$coin = Db::name('app_rate')
->where('symbol',$symbol)->find();
if($coin) {
$tradejson = json_decode($coin['tradectrl_json'],true);
$trademulte_json = json_decode($coin['trademulte_json'],true);
$price = $num = 0;
if(!empty($tradejson)) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
$num = $this->randomFloat(1, 10, 6);
break;
}
}
if ($price > 0) {
$data['tick']['close'] = $price;
}
}
if(!empty($trademulte_json) && $price <= 0){
// $this->saveLog("arusdt", "--".$data['tick']['close']."--".$symbol);
foreach ($trademulte_json as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = $data['tick']['close']*$value;
$data['tick']['open'] = $data['tick']['open']*$value;
$ch_arr = explode(".", $data['ch']);
if(isset($ch_arr[3]) && $ch_arr[3]=="1day"){
if($value > 1){
$data['tick']['low'] = $data['tick']['low']*$value;
$data['tick']['high'] = $data['tick']['high']*$value;
}else{
$data['tick']['high'] = $data['tick']['high']*$value;
$data['tick']['low'] = $data['tick']['low']*$value;
}
}else{
$data['tick']['high'] = $data['tick']['high']*$value;
$data['tick']['low'] = $data['tick']['low']*$value;
}
$num = $this->randomFloat(1, 10, 6);
break;
}
}
if ($price > 0) {
$data['tick']['close'] = $price;
}
}
}
}
if($symbol && $this->ctrl && isset($this->ctrl[$symbol]) && isset($this->ctrl[$symbol][time()]))
{
$data['tick']['close'] = (float)sprintf("%.2f",$this->ctrl[$symbol][time()]);
// $this->saveLog("all", '调控数据推送:'.json_encode($data));
}
foreach ($this->userdy[$data['ch']] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->userdy[$data['ch']][$key]);
} else {
if(in_array($value,$this->userctrldy)){
$datass = $data;
$userids = array_search($value, $this->userctrldy);
$pricearr = [];
if(isset($this->userctrl[$userids]))
{
$tradejson = json_decode($this->userctrl[$userids],true);
if($tradejson) {
foreach ($tradejson as $kk => $vv) {
if ($symbol && $symbol == $kk) {
$jsonarr = explode('|', $vv);
$time1 = explode('-', $jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$pricearr = explode('-', $jsonarr[1]);
break;
}
}
}
}
}
if($pricearr){
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
if ($price > 0) {
$datass['tick']['close'] = $price;
if($price > $datass['tick']['high']){
$datass['tick']['high'] = $pricearr[1];
}
if($price < $datass['tick']['low']){
$datass['tick']['high'] = $pricearr[1];
}
if($datass['tick']['open'] < $pricearr[0]){
$datass['tick']['open'] = $pricearr[0];
}
}
}
$redis_price = $this->redis->get($symbol);
if($redis_price){
$price_bl = abs(($datass['tick']['close']-$redis_price)/$redis_price*100);
if($price_bl<30){
$this->redis->set($symbol,$datass['tick']['close']);
$time_str = strtotime(date("Y-m-d H:i"));
$this->redis->set($symbol."-".$time_str,$datass['tick']['close'],180);
$worker->connections[$value]->send(json_encode($datass));
}else{
$this->saveLog($symbol."-error", '--上一條價:'.$redis_price.",最新價:".$datass['tick']['close']);
}
}else{
$this->redis->set($symbol,$datass['tick']['close']);
}
}else{
$worker->connections[$value]->send(json_encode($data));
}
}
}
}else if(strpos($data['ch'],'depth') !== false)
{
$data['subs'] = 'depth';
$symbol = '';
foreach ($this->coins as $kk => $vv)
{
$data_ch = explode(".",$data['ch']);
// if (strpos($data['ch'], $vv['symbol']) !== false){
if (isset($data_ch[1]) && $data_ch[1] == $vv['symbol']){
$symbol = $vv['symbol'];
$jd = $vv['jd'];
break;
}
}
$hour = date('H');
$minute = date('i');
if ($symbol) {
$coin = Db::name('app_rate')
->where('symbol',$symbol)->find();
if($coin) {
$tradejson = json_decode($coin['tradectrl_json'],true);
$trademulte_json = json_decode($coin['trademulte_json'],true);
$price = $num = 0;
$pricearrs = [];
if(!empty($tradejson)) {
foreach ($tradejson as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearr = explode('-', $value);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
$num = $this->randomFloat(1, 10, 6);
$pricearrs = $pricearr;
break;
}
}
if (!empty($pricearrs)) {
//买一价格
$bidsprice = $pricearrs[0];
$bidsprices = $bidsprice;
//卖一价格
$asksprice = $pricearrs[1];
$asksprices = $asksprice;
foreach ($data['tick']['bids'] as $key=>$value)
{
$value[0] = $bidsprices - (float)$this->randomFloat($bidsprices*0.01, $bidsprices*0.02, $jd);
$data['tick']['bids'][$key] = $value;
$bidsprices = $value[0];
}
foreach ($data['tick']['asks'] as $key=>$value)
{
$value[0] = $asksprices + (float)$this->randomFloat($bidsprices*0.01, $bidsprices*0.02, $jd);
$data['tick']['asks'][$key] = $value;
$asksprices = $value[0];
}
}
}
if(!empty($trademulte_json) && empty($pricearrs)) {
foreach ($trademulte_json as $key => $value) {
$time1 = explode('-', $key);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
// $price = (float)$this->randomFloat($pricearr[0], $pricearr[1], $jd);
// $num = $this->randomFloat(1, 10, 6);
$pricearrs = $value;
break;
}
}
if (!empty($pricearrs)) {
foreach ($data['tick']['bids'] as $key=>$value)
{
$value[0] = $value[0] * $pricearrs;
$data['tick']['bids'][$key] = $value;
$bidsprices = $value[0];
}
foreach ($data['tick']['asks'] as $key=>$value)
{
$value[0] = $value[0] * $pricearrs;
$data['tick']['asks'][$key] = $value;
$asksprices = $value[0];
}
}
}
}
}
foreach ($this->usersd[$data['ch']] as $key => $value) {
if (!isset($worker->connections[$value])) {
unset($this->usersd[$data['ch']][$key]);
} else {
if(in_array($value,$this->userctrldy)){
$datass = $data;
$userids = array_search($value, $this->userctrldy);
$pricearrs = [];
if(isset($this->userctrl[$userids]))
{
$tradejson = json_decode($this->userctrl[$userids],true);
if($tradejson) {
foreach ($tradejson as $kk => $vv) {
if ($symbol && $symbol == $kk) {
$jsonarr = explode('|', $vv);
$time1 = explode('-', $jsonarr[0]);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$pricearrs = explode('-', $jsonarr[1]);
break;
}
}
}
}
}
if (!empty($pricearrs)) {
//买一价格
$bidsprice = $pricearrs[0];
$bidsprices = $bidsprice;
//卖一价格
$asksprice = $pricearrs[1];
$asksprices = $asksprice;
foreach ($datass['tick']['bids'] as $kks=>$vals)
{
$vals[0] = $bidsprices - (float)$this->randomFloat($bidsprices*0.01, $bidsprices*0.02, $jd);
$datass['tick']['bids'][$kks] = $vals;
$bidsprices = $vals[0];
}
foreach ($datass['tick']['asks'] as $kks=>$vals)
{
$vals[0] = $asksprices + (float)$this->randomFloat($bidsprices*0.01, $bidsprices*0.02, $jd);
$datass['tick']['asks'][$kks] = $vals;
$asksprices = $vals[0];
}
}
$worker->connections[$value]->send(json_encode($datass));
}else{
$worker->connections[$value]->send(json_encode($data));
}
}
}
}
}else if (isset($data['rep'])){
$data['subs'] = 'history';
$data['ch'] = $data['rep'];
foreach ($data['data'] as $key=>$value)
{
// $value['time'] = $value['id'] * 1000;
$data['data'][$key] = $value;
}
$worker->connections[$this->historykline[$data['id']]]->send(json_encode($data));
}
}
function saveLog($symbol, $msg){
$dir = __DIR__ ."/logs";
if( !file_exists($dir) ) mkdir($dir, 0777);
$today = date('Ymd');
$file_path =$dir."/a-".$symbol."-".$today.".log";
$handle = fopen($file_path, "a+");
@fwrite($handle, date("H:i:s"). $msg . "\r\n");
@fclose($handle);
}
//4位小数的随机数
function randomFloat($min = 0, $max = 10 , $localnum = 4)
{
if($localnum == 4) {
if ($max - $min <= 0.0002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.0001);
$num = $min + $rand;
$number = sprintf("%.4f", $num);
if($number == $min){
$number += 0.0001;
}
}else if($localnum == 5){
if ($max - $min <= 0.00002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.00001);
$num = $min + $rand;
$number = sprintf("%.5f", $num);
if($number == $min){
$number += 0.00001;
}
}else if($localnum == 6){
if ($max - $min <= 0.000002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.000001);
$num = $min + $rand;
$number = sprintf("%.6f", $num);
if($number == $min){
$number += 0.000001;
}
}else if($localnum == 2){
if ($max - $min <= 0.02) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.01);
$num = $min + $rand;
$number = sprintf("%.2f", $num);
if($number == $min){
$number += 0.01;
}
}else if($localnum == 3){
if ($max - $min <= 0.001) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.001);
$num = $min + $rand;
$number = sprintf("%.3f", $num);
if($number == $min){
$number += 0.001;
}
}
return $number;
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* 回调接口
*/
class Notify extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = [''];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
public function index()
{
$parem = $this->request->request();
file_put_contents("./notify.text", json_encode($parem)."\r\n",FILE_APPEND);
}
}
+305
View File
@@ -0,0 +1,305 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* 投资接口
*/
class Product extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
/**
* 投资首页
*/
public function index_list()
{
$list = Db::name("app_product")->field("id,name,logo_image,min_num,max_num,fast_rixi,day,rixi_json")
->where("status",1)
->order("weigh desc")
->select();
foreach ($list as $key => $value) {
$rixi_json = json_decode($value['rixi_json'],true);
$rixi = min($rixi_json)."%-".max($rixi_json)."%";
$value['logo_image'] = Config::get("site.image_url").$value['logo_image'];
$value['rixi'] = $rixi;
unset($value['rixi_json']);
$list[$key] = $value;
}
$this->success("ok",$list);
}
/**
* 投资详情
*/
public function product_con()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
$product = Db::name("app_product")->field("id,name,logo_image,min_num,max_num,fast_rixi,day,rixi_json,msg,curr_id")
->where("id",$id)
->where("status",1)
->find();
if(!$product){
$this->error(__("产品不存在或已下架"));
}
$curr = Db::name("app_currency")->where("id",$product['curr_id'])->find();
$product['curr_name'] = $curr['name'];
$product['money_trx'] = Db::name("app_currency_user")->where("user_id",$user_id)->where("curr_id",$product['curr_id'])->value("num");
//我的投资
// $my_num = Db::name("app_product_user")->where("user_id",$user_id)->where("status",1)->sum("num");
$rixi_json = json_decode($product['rixi_json'],true);
$rixi = min($rixi_json);
$rixi_arr = [];
foreach ($rixi_json as $key => $value) {
$rixi_arr[] = array(
"key" => $key,
"value" => $value,
);
}
$product['rixi'] = $rixi;
$product['rixi_arr'] = $rixi_arr;
unset($product['rixi_json']);
unset($product['fast_rixi']);
$this->success("ok",$product);
}
/**
* 立即投资
*/
public function product_buy()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
$num = $this->request->post("num");
$pay_pwd = $this->request->post("pay_pwd");
//判断交易密码
if(strtoupper(md5(strtoupper(md5($pay_pwd.'skund')))) != $this->auth->pay_pwd)
{
$this->error(__('交易密码错误'));
}
$product = Db::name("app_product")->field("id,name,logo_image,min_num,max_num,fast_rixi,day,rixi_json,curr_id")
->where("id",$id)
->where("status",1)
->find();
if(!$product){
$this->error(__("产品不存在或已下架"));
}
if($num < $product['min_num']){
$this->error(__("最低投资数量:").$product['min_num']);
}
if($num > $product['max_num']){
$this->error(__("最高投资数量:").$product['max_num']);
}
$trx_curr = Db::name("app_currency_user")->where("user_id",$user_id)->where("curr_id",$product['curr_id'])->find();
if($trx_curr['num'] < $num){
$this->error(__("余额不足"));
}
//redis防重复点击
$symbol = "product_buy" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
//我的投资
// $my_num = Db::name("app_product_user")->where("user_id",$user_id)->where("status",1)->sum("num");
$rixi_json = json_decode($product['rixi_json'],true);
$rixi = min($rixi_json);
foreach ($rixi_json as $key => $value) {
if($num >= $key){
$rixi = $value;
}
}
$data = array(
"user_id" => $user_id,
"product_id" => $id,
"curr_id" => $product['curr_id'],
"rixi" => $rixi,
"num" => $num,
"day" => $product['day'],
"alr_day" => 0,
"alr_num" => 0,
"status" => 1,
"addtime" => time(),
"lasttime" => time(),
);
$detailed_data = array(
"user_id" => $user_id,
"curr_id" => $trx_curr['curr_id'],
"price" => $num,
"cart" => 2,
"type" => 11,
"description" => "产品投资",
"createtime" => time(),
"before_num" => $trx_curr['num'],
"after_num" => $trx_curr['num'] - $num,
);
Db::startTrans();
try {
Db::name("app_product_user")->insert($data);
Db::name("app_detailed")->insert($detailed_data);
Db::name("app_currency_user")->where("id",$trx_curr['id'])->setDec("num",$num);
Db::commit();
$this->success( __("提交成功") );
} catch (Exception $e) {
Db::rollback();
lopRedis($symbol);
$this->error( __( "网络错误,请稍后再试!" ) );
}
}
/**
* 投资记录
*/
public function product_user()
{
$user_id = $this->auth->id;
$list = Db::name("app_product_user a")->field("a.id,b.name,a.num,a.rixi,a.day,a.addtime,a.status,c.name as curr_name")
->join("app_product b","a.product_id=b.id","left")
->join("app_currency c","a.curr_id=c.id","left")
->where("a.user_id",$user_id)
->order("a.id desc")
->select();
foreach ($list as $key => $value) {
$value['addtime'] = date("Y-m-d H:i",$value['addtime']);
$list[$key] = $value;
}
$this->success("ok",$list);
}
/**
* 投资记录-详情
*/
public function product_user_con()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
$product = Db::name("app_product_user")->field("id,alr_day,alr_num,curr_id")->where("user_id",$user_id)->where("id",$id)->find();
if(empty($product)){
$this->error(__("产品不存在或已下架"));
}
$product['curr_name'] = Db::name("app_currency")->where("id",$product['curr_id'])->value("name");
$this->success("ok",$product);
}
/**
* 产品-释放记录
*/
public function product_user_log()
{
$user_id = $this->auth->id;
$id = $this->request->post("id");
// $detail_log = Db::name("app_detailed")->field("price,createtime")
// ->where("user_id",$user_id)
// ->where("type",4)
// ->where("pro_id",$id)
// ->order("id desc")
// ->paginate(20, false, ['query' => request()->param()]);
$detail_log = Db::name("app_product_log")->field("num as price,addtime as createtime")
->where("pro_id",$id)
->order("id desc")
->paginate(20, false, ['query' => request()->param()]);
foreach ($detail_log as $key => $value) {
$value['createtime'] = date("Y-m-d H:i",$value['createtime']);
$detail_log[$key] = $value;
}
$this->success("ok",$detail_log);
}
/**
* 每日日息产生
*/
public function set_rixi()
{
$product = Db::name("app_product_user a")->field("a.*,b.exchange,u.path")
->join("app_currency b","a.curr_id=b.id","left")
->join("user u","a.user_id=u.id","left")
->where("a.status",1)
->where("a.lasttime","<", time()-86400)
->order("a.lasttime asc")
->limit(20)
->select();
if(empty($product)){
echo "暂无产品";exit;
}
foreach ($product as $key => $value) {
if($value['alr_day'] >= $value['day']){
Db::name("app_product_user")->where("id",$value['id'])->update(['status'=>0]);
continue;
}
$detail_log = [];
Db::startTrans();
try {
//释放对应币种
$sf_num = sprintf("%.8f",$value['rixi']*$value['num']/100);
//应释放USDT量
// $usdt_num = sprintf("%.8f",$sf_num*$value['exchange']);
$update = array(
"alr_day" => $value['alr_day']+1,
"alr_num" => $value['alr_num']+$sf_num,
"lasttime" => time(),
);
$pro_log = array(
"pro_id" => $value['id'],
"num" => $sf_num,
"addtime" => time(),
);
Db::name("app_product_log")->insert($pro_log);
if($update['alr_day']>=$value['day']){
$update['status'] = 0;
//退还本金
$user_trx = Db::name('app_currency_user')->where("user_id",$value['user_id'])->where("curr_id",$value['curr_id'])->find();
$detail_log[] = array(
"user_id" => $user_trx['user_id'],
"curr_id" => $user_trx['curr_id'],
"price" => $value['num'],
"cart" => 1,
"type" => 11,
"description" => "理财本金退还",
"createtime" => time(),
"notice" => "产品ID".$value['id'],
"before_num" => $user_trx['num'],
"after_num" => $user_trx['num']+$value['num'],
"pro_id" => 0,
);
//一次性反息
$detail_log[] = array(
"user_id" => $user_trx['user_id'],
"curr_id" => $user_trx['curr_id'],
"price" => $update['alr_num'],
"cart" => 1,
"type" => 11,
"description" => "理财利息",
"createtime" => time(),
"notice" => "产品ID".$value['id'],
"before_num" => $user_trx['num'],
"after_num" => $user_trx['num']+$value['num']+$update['alr_num'],
"pro_id" => 0,
);
Db::name('app_currency_user')->where("id",$user_trx['id'])->update(['num'=>$user_trx['num']+$value['num']+$update['alr_num']]);
}
if($detail_log){
Db::name("app_detailed")->insertAll($detail_log);
}
Db::name("app_product_user")->where("id",$value['id'])->update($update);
Db::commit();
} catch (Exception $e) {
Db::rollback();
echo '数据插入失败';
}
echo $value['id']."--";
}
echo "success";
}
}
+138
View File
@@ -0,0 +1,138 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
/**
* 公共接口
*/
class Publics extends Api
{
protected $noNeedLogin = "*";
protected $noNeedRight = '*';
//获取相关配置数据
public function get_common_data()
{
$lang = $this->request->request("lang");
switch ($lang) {
case "zh-cn":
$about_us = Config::get("site.about_us");
$user_item = Config::get("site.user_item");
$privacy_treaty = Config::get("site.privacy_treaty");
$agreement = Config::get("site.agreement");
break;
default:
$about_us = Config::get("site.about_us_en");
$user_item = Config::get("site.user_item_en");
$privacy_treaty = Config::get("site.privacy_treaty_en");
$agreement = Config::get("site.agreement_en");
break;
}
$data = [
'about_us' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $about_us), //关于我们
'user_item' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $user_item), //用户条款
'privacy_treaty' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $privacy_treaty), //隐私条约
'agreement' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $agreement), //用户协议
'web_url' => Config::get("site.web_url"),
];
$this->success('success',$data);
}
/**
* 新增文案
*/
public function new_common_data()
{
$lang = $this->request->request("lang");
switch ($lang) {
case "zh-cn":
$huilv_text = Config::get("site.huilv_text");
$api_text = Config::get("site.api_text");
$api_sq_text = Config::get("site.api_sq_text");
$shouquan_text = Config::get("site.shouquan_text");
$refund_text = Config::get("site.refund_text");
break;
default:
$huilv_text = Config::get("site.huilv_text");
$api_text = Config::get("site.api_text");
$api_sq_text = Config::get("site.api_sq_text");
$shouquan_text = Config::get("site.shouquan_text");
$refund_text = Config::get("site.refund_text_en");
break;
}
$data = [
'exchange_rate' => Config::get("site.exchange_rate"),
'huilv_text' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $huilv_text), //汇率文案
'api_text' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $api_text), //API文案
'api_sq_text' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $api_sq_text), //API申请须知
'shouquan_text' => str_replace("src=\"","src=\"".Config::get("site.image_url"), $shouquan_text), //授权管理文案
'refund_text' => $refund_text,
];
$this->success('success',$data);
}
/**
* 版本信息
*/
public function version()
{
$res = Db::name("version")->where("status","normal")->order("id desc")->find();
if($res['type'] == 2){
if($this->auth->user_type != 2){
$res = Db::name("version")->where("status","normal")->where("type",1)->order("id desc")->find();
}
}
$this->success('success',$res);
}
/**
* 获取平台logo
*/
public function logo()
{
$logo = Config::get("site.image_url").Config::get("site.logo");
$data = array(
"logo" => $logo,
);
$this->success('返回成功', $data);
}
/**
* 图片上传
*/
public function image_upload()
{
// $this->error("网络延迟,请稍后再试");
$file_url = "/uploads/image";
controller('Common')->iamge_upload_single($file_url);
}
/**
* 官网信息返回
*/
public function website()
{
$download_a = Config::get("site.image_url").Config::get("site.download_a");
$download_i = Config::get("site.image_url").Config::get("site.download_i");
$data = array(
"download_a" => $download_a,
"download_i" => $download_i,
);
$this->success('返回成功', $data);
}
/**
* 费率列表
*/
public function exchange_list()
{
$list = Db::name("app_exchange_set")->field("id,name,name_sx,exchange")->select();
$this->success('返回成功', $list);
}
}
+123
View File
@@ -0,0 +1,123 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\library\Sms as Smslib;
use app\common\model\User;
use think\Hook;
/**
* 手机短信接口
*/
class Sms extends Api
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
/**
* 发送验证码
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $event 事件名称
*/
public function send()
{
$mobile = $this->request->request("mobile");
$ip = $_SERVER['HTTP_USER_AGENT'].$mobile;
if( !empty($_SERVER['HTTP_VIA']) ) //使用了代理
{
$this->success(__('发送成功.'));
}
$event = $this->request->request("event");
$m_prefix = $this->request->request("m_prefix","");
$event = $event ? $event : 'register';
if($m_prefix == "+86"){
$this->error(__('根据当地区法律规定,暂不支持该地区注册'));
}
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{6}|\d{10}$")) {
// $this->error(__('手机号不正确'));
}
$last = Smslib::get($mobile, $event);
if ($last && time() - $last['createtime'] < 60) {
$this->error(__('发送频繁'));
}
$ipSendTotal = \app\common\model\Sms::where(['ip' => $this->request->ip()])->count();
if ($ipSendTotal >= 100) {
$this->error(__('发送频繁'));
}
$userinfo = User::getByMobile($mobile);
if ($event) {
if ($event == 'register' && $userinfo) {
//已被注册
$this->error(__('已被注册'));
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->error(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
//未注册
$this->error(__('未注册'));
}
}
if (!Hook::get('sms_send')) {
$this->error(__('请在后台插件管理安装短信验证插件'));
}
if($m_prefix){
$userinfo['m_prefix'] = $m_prefix;
}else{
if(!$userinfo || !$userinfo['m_prefix']){
$userinfo['m_prefix'] = "886";
}
}
// var_dump($userinfo);exit;
$ret = Smslib::send($mobile, null, $event , $userinfo['m_prefix'] );
if ($ret) {
$this->success(__('发送成功'));
} else {
$this->error(__('发送失败.'));
}
}
/**
* 检测验证码
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $event 事件名称
* @param string $captcha 验证码
*/
public function check()
{
$mobile = $this->request->post("mobile");
$event = $this->request->post("event");
$event = $event ? $event : 'register';
$captcha = $this->request->post("captcha");
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号不正确'));
}
if ($event) {
$userinfo = User::getByMobile($mobile);
if ($event == 'register' && $userinfo) {
//已被注册
$this->error(__('已被注册'));
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->error(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
//未注册
$this->error(__('未注册'));
}
}
$ret = Smslib::check($mobile, $captcha, $event);
if ($ret) {
$this->success(__('成功'));
} else {
$this->error(__('验证码不正确'));
}
}
}
File diff suppressed because it is too large Load Diff
+295
View File
@@ -0,0 +1,295 @@
<?php
/**
* Created by PhpStorm.
* User: cchhyy
* Date: 2021/2/4
* Time: 5:39 PM
*/
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
use think\Config;
ignore_user_abort(); // 后台运行
set_time_limit(0); // 取消脚本运行时间的超时上限
/**
* 首页接口
*/
class Synccoin extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function test()
{
$i = 1;
while($i<=10000)
{
$this->saveLog("test", '定时循环:'.$i);
$i++;
sleep(1);
}
}
//btcusdt
public function syncbtcusdt()
{
// $i = 1;
// while(1)
// {
$data = json_decode(http_curl('https://api.huobi.pro/market/history/trade?period=1min&size=20&symbol=btcusdt','get')
,true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
$this->saveLog("sync_btcusdt", '————数据错误:' . json_encode($data));
}else {
$btcusdt = Db::name('hb_1s_btc')->order('ts', 'desc')
->limit(20)->select();
$btcarr = array_column($btcusdt,'id','ts');
$data1 = $data['data'];
// $nextsecond = $btcusdt[0]['ts'];
$datas = array_column($data1, 'ts');
array_multisort($datas, SORT_ASC, $data1);
$havedata = [];
$insert = [];
foreach ($data1 as $key => $value) {
$nextsecond = substr($value['ts'],0,10);
$nextseconds = $nextsecond.'000';
if(!in_array($nextsecond,$havedata) && !isset($btcarr[$nextsecond])){
foreach ($data['data'] as $k=>$val)
{
if(strpos($val['ts'],$nextsecond) !== false)
{
$pricedata = $val['data'][0];
break;
}
}
$insert[] = [
'symbol' => 'btcusdt',
'ts' => $nextsecond,
'price' => $pricedata['price'],
'amount' => $pricedata['amount'],
];
$havedata[] = $nextsecond;
}
}
if(!empty($insert))
{
Db::name('hb_1s_btc')->insertAll($insert);
}
$this->saveLog("sync_btcusdt", 'btcusdt价格同步到:' . date('Y-m-d H:i:s',$nextsecond));
}
// $i++;
// }
}
public function syncethusdt()
{
$data = json_decode(http_curl('https://api.huobi.pro/market/history/trade?period=1min&size=20&symbol=ethusdt','get')
,true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
$this->saveLog("sync_ethusdt", '————数据错误:' . json_encode($data));
}else {
$btcusdt = Db::name('hb_1s_eth')->order('ts', 'desc')
->limit(20)->select();
$btcarr = array_column($btcusdt,'id','ts');
$data1 = $data['data'];
// $nextsecond = $btcusdt[0]['ts'];
$datas = array_column($data1, 'ts');
array_multisort($datas, SORT_ASC, $data1);
$havedata = [];
$insert = [];
foreach ($data1 as $key => $value) {
$nextsecond = substr($value['ts'],0,10);
$nextseconds = $nextsecond.'000';
if(!in_array($nextsecond,$havedata) && !isset($btcarr[$nextsecond])){
foreach ($data['data'] as $k=>$val)
{
if(strpos($val['ts'],$nextsecond) !== false)
{
$pricedata = $val['data'][0];
break;
}
}
$insert[] = [
'symbol' => 'ethusdt',
'ts' => $nextsecond,
'price' => $pricedata['price'],
'amount' => $pricedata['amount'],
];
$havedata[] = $nextsecond;
}
}
if(!empty($insert))
{
Db::name('hb_1s_eth')->insertAll($insert);
}
$this->saveLog("sync_ethusdt", 'ethusdt价格同步到:' . date('Y-m-d H:i:s',$nextsecond));
}
}
public function syncltcusdt()
{
$data = json_decode(http_curl('https://api.huobi.pro/market/history/trade?period=1min&size=20&symbol=ltcusdt','get')
,true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
$this->saveLog("sync_ltcusdt", '————数据错误:' . json_encode($data));
}else {
$btcusdt = Db::name('hb_1s_ltc')->order('ts', 'desc')
->limit(20)->select();
$btcarr = array_column($btcusdt,'id','ts');
$data1 = $data['data'];
// $nextsecond = $btcusdt[0]['ts'];
$datas = array_column($data1, 'ts');
array_multisort($datas, SORT_ASC, $data1);
$havedata = [];
$insert = [];
foreach ($data1 as $key => $value) {
$nextsecond = substr($value['ts'],0,10);
$nextseconds = $nextsecond.'000';
if(!in_array($nextsecond,$havedata) && !isset($btcarr[$nextsecond])){
foreach ($data['data'] as $k=>$val)
{
if(strpos($val['ts'],$nextsecond) !== false)
{
$pricedata = $val['data'][0];
break;
}
}
$insert[] = [
'symbol' => 'ltcusdt',
'ts' => $nextsecond,
'price' => $pricedata['price'],
'amount' => $pricedata['amount'],
];
$havedata[] = $nextsecond;
}
}
if(!empty($insert))
{
Db::name('hb_1s_ltc')->insertAll($insert);
}
$this->saveLog("sync_ltcusdt", 'ltcusdt价格同步到:' . date('Y-m-d H:i:s',$nextsecond));
}
}
public function syncbchusdt()
{
$data = json_decode(http_curl('https://api.huobi.pro/market/history/trade?period=1min&size=20&symbol=bchusdt','get')
,true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
$this->saveLog("sync_bchusdt", '————数据错误:' . json_encode($data));
}else {
$btcusdt = Db::name('hb_1s_bch')->order('ts', 'desc')
->limit(20)->select();
$btcarr = array_column($btcusdt,'id','ts');
$data1 = $data['data'];
// $nextsecond = $btcusdt[0]['ts'];
$datas = array_column($data1, 'ts');
array_multisort($datas, SORT_ASC, $data1);
$havedata = [];
$insert = [];
foreach ($data1 as $key => $value) {
$nextsecond = substr($value['ts'],0,10);
$nextseconds = $nextsecond.'000';
if(!in_array($nextsecond,$havedata) && !isset($btcarr[$nextsecond])){
foreach ($data['data'] as $k=>$val)
{
if(strpos($val['ts'],$nextsecond) !== false)
{
$pricedata = $val['data'][0];
break;
}
}
$insert[] = [
'symbol' => 'bchusdt',
'ts' => $nextsecond,
'price' => $pricedata['price'],
'amount' => $pricedata['amount'],
];
$havedata[] = $nextsecond;
}
}
if(!empty($insert))
{
Db::name('hb_1s_bch')->insertAll($insert);
}
$this->saveLog("sync_bchusdt", 'bchusdt价格同步到:' . date('Y-m-d H:i:s',$nextsecond));
}
}
public function synceosusdt()
{
$data = json_decode(http_curl('https://api.huobi.pro/market/history/trade?period=1min&size=20&symbol=eosusdt','get')
,true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
$this->saveLog("sync_eosusdt", '————数据错误:' . json_encode($data));
}else {
$btcusdt = Db::name('hb_1s_eos')->order('ts', 'desc')
->limit(20)->select();
$btcarr = array_column($btcusdt,'id','ts');
$data1 = $data['data'];
// $nextsecond = $btcusdt[0]['ts'];
$datas = array_column($data1, 'ts');
array_multisort($datas, SORT_ASC, $data1);
$havedata = [];
$insert = [];
foreach ($data1 as $key => $value) {
$nextsecond = substr($value['ts'],0,10);
$nextseconds = $nextsecond.'000';
if(!in_array($nextsecond,$havedata) && !isset($btcarr[$nextsecond])){
foreach ($data['data'] as $k=>$val)
{
if(strpos($val['ts'],$nextsecond) !== false)
{
$pricedata = $val['data'][0];
break;
}
}
$insert[] = [
'symbol' => 'eosusdt',
'ts' => $nextsecond,
'price' => $pricedata['price'],
'amount' => $pricedata['amount'],
];
$havedata[] = $nextsecond;
}
}
if(!empty($insert))
{
Db::name('hb_1s_eos')->insertAll($insert);
}
$this->saveLog("sync_eosusdt", 'eosusdt价格同步到:' . date('Y-m-d H:i:s',$nextsecond));
}
}
function saveLog($symbol, $msg){
$dir = __DIR__ ."/logs";
if( !file_exists($dir) ) mkdir($dir, 0777);
$today = date('Ymd');
$file_path =$dir."/".$symbol."-".$today.".log";
$handle = fopen($file_path, "a+");
@fwrite($handle, date("H:i:s"). $msg . "\r\n");
@fclose($handle);
}
}
+2359
View File
File diff suppressed because it is too large Load Diff
+844
View File
@@ -0,0 +1,844 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use fast\Random;
use think\Db;
use think\Config;
use function fast\e;
/**
* 币币交易
*/
class TaskTrade extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function millisecondWay(){
list($s1, $s2) = explode(' ', microtime());
return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
}
public function get_redis()
{
$redis = getRedis();
$time_str = strtotime(date("Y-m-d H:i"));
$key = 'aeusdt-'.$time_str;
$test1 = $redis->get($key);
$key2 = 'aeusdt-'.($time_str-60);
$test2 = $redis->get($key2);
$key3 = 'aeusdt-'.($time_str-120);
$test3 = $redis->get($key3);
$key4 = 'aeusdt-'.($time_str-240);
$test4 = $redis->get($key4);
var_dump($test1,$test2,$test3,$test4);
}
/**
* 获取最新K线
*/
public function get_kline($id)
{
$release = Db::name("app_curr_release")->where("id",$id)->find();
if($release['status'] == 1 || $release['status'] == 0){
echo "未上架";exit;
}
$rate = Db::name("app_rate")->where("symbol",$release['symbol'])->find();
$hour = date('H');
$minute = date('i');$buy_price=0;$sell_price=0;
$pricearr = [];
$tradejson = json_decode($release['tradectrl_json'],true);
$trademulte_json = json_decode($release['trademulte_json'],true);
if($tradejson) {
foreach ($tradejson as $kk => $vv) {
$time1 = explode('-', $kk);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
$pricearrs = explode('-', $vv);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$pricearr = $pricearrs;
break;
}
}
}
if($trademulte_json && empty($pricearr)){
foreach ($trademulte_json as $kk => $vv) {
$time1 = explode('-', $kk);
$time2 = explode(':', $time1[0]);
$time3 = explode(':', $time1[1]);
// $pricearrs = explode('-', $vv);
if ($hour >= $time2[0] && $hour <= $time3[0]) {
if (($hour == $time3[0] && $minute > $time3[1]) || ($hour == $time2[0] && $minute < $time2[1])) continue;
$datass = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=1min&size=1&symbol='.$release['symbol'],'get'),true);
if(!$datass || !isset($datass['data']) || empty($datass['data']))
{
var_dump($datass);exit;
}
$rate['close'] = $datass['data'][0]['close'] * $vv;
$buy_price = $datass['data'][0]['low'] * $vv;
$sell_price = $datass['data'][0]['high'] * $vv;
$new_price = $rate['close'];
// var_dump($vv,'-----');
break;
}
}
}
$new_price = $rate['close'];
if($pricearr){
$price = (float)$this->randomFloat($pricearr[0], $pricearr[1], 4);
if ($price > 0) {
$new_price = $price;
}
$buy_price = $pricearr[0];
$sell_price = $pricearr[1];
}
// var_dump($new_price,$sell_price,$buy_price);exit;
if($release['is_tk'] == 0 || $buy_price==0 || $sell_price==0){
//未调控价格
//1分钟
$data = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=1min&size=2&symbol='.$release['symbol'],'get'),true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
var_dump($data);exit;
}else {
$data1 = $data['data'];
unset($data1[0]);//去掉最新一条
$datas = array_column($data1, 'id');
array_multisort($datas, SORT_ASC, $data1);
$last_kline = Db::name("bb_k_1min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$insert = [];
foreach ($data1 as $key => $value) {
if(empty($last_kline) || $last_kline['ts'] < $value['id']){
$insert[] = [
'symbol' => $release['symbol'],
'ts' => $value['id'],
'open' => $value['open'],
'close' => $value['close'],
'low' => $value['low'],
'high' => $value['high'],
'vol' => $value['vol'],
'count' => $value['count'],
];
}
}
if(!empty($insert))
{
Db::name('bb_k_1min')->insertAll($insert);
echo "1min";
}
}
//5分钟
$data = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=5min&size=2&symbol='.$release['symbol'],'get'),true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
var_dump($data);exit;
}else {
$data1 = $data['data'];
unset($data1[0]);//去掉最新一条
$datas = array_column($data1, 'id');
array_multisort($datas, SORT_ASC, $data1);
$last_kline = Db::name("bb_k_5min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$insert = [];
foreach ($data1 as $key => $value) {
if((empty($last_kline) || $last_kline['ts'] < $value['id']) && $value['id']<=time()){
$insert[] = [
'symbol' => $release['symbol'],
'ts' => $value['id'],
'open' => $value['open'],
'close' => $value['close'],
'low' => $value['low'],
'high' => $value['high'],
'vol' => $value['vol'],
'count' => $value['count'],
];
}
}
if(!empty($insert))
{
Db::name('bb_k_5min')->insertAll($insert);
echo "5min";
}
}
//15分钟
$data = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=15min&size=2&symbol='.$release['symbol'],'get'),true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
var_dump($data);exit;
}else {
$data1 = $data['data'];
unset($data1[0]);//去掉最新一条
$datas = array_column($data1, 'id');
array_multisort($datas, SORT_ASC, $data1);
$last_kline = Db::name("bb_k_15min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$insert = [];
foreach ($data1 as $key => $value) {
if((empty($last_kline) || $last_kline['ts'] < $value['id']) && $value['id']<=time()){
$insert[] = [
'symbol' => $release['symbol'],
'ts' => $value['id'],
'open' => $value['open'],
'close' => $value['close'],
'low' => $value['low'],
'high' => $value['high'],
'vol' => $value['vol'],
'count' => $value['count'],
];
}
}
if(!empty($insert))
{
Db::name('bb_k_15min')->insertAll($insert);
echo "15min";
}
}
//30分钟
$data = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=30min&size=2&symbol='.$release['symbol'],'get'),true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
var_dump($data);exit;
}else {
$data1 = $data['data'];
unset($data1[0]);//去掉最新一条
$datas = array_column($data1, 'id');
array_multisort($datas, SORT_ASC, $data1);
$last_kline = Db::name("bb_k_30min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$insert = [];
foreach ($data1 as $key => $value) {
if((empty($last_kline) || $last_kline['ts'] < $value['id']) && $value['id']<=time()){
$insert[] = [
'symbol' => $release['symbol'],
'ts' => $value['id'],
'open' => $value['open'],
'close' => $value['close'],
'low' => $value['low'],
'high' => $value['high'],
'vol' => $value['vol'],
'count' => $value['count'],
];
}
}
if(!empty($insert))
{
Db::name('bb_k_30min')->insertAll($insert);
echo "30min";
}
}
//60分钟
$data = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=60min&size=2&symbol='.$release['symbol'],'get'),true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
var_dump($data);exit;
}else {
$data1 = $data['data'];
unset($data1[0]);//去掉最新一条
$datas = array_column($data1, 'id');
array_multisort($datas, SORT_ASC, $data1);
$last_kline = Db::name("bb_k_1h")->where("symbol",$release['symbol'])->order("ts desc")->find();
$insert = [];
foreach ($data1 as $key => $value) {
if((empty($last_kline) || $last_kline['ts'] < $value['id']) && $value['id']<=time()){
$insert[] = [
'symbol' => $release['symbol'],
'ts' => $value['id'],
'open' => $value['open'],
'close' => $value['close'],
'low' => $value['low'],
'high' => $value['high'],
'vol' => $value['vol'],
'count' => $value['count'],
];
}
}
if(!empty($insert))
{
Db::name('bb_k_1h')->insertAll($insert);
echo "1h";
}
}
//24小时
$data = json_decode(http_curl('https://api.huobi.pro/market/history/kline?period=1day&size=1&symbol='.$release['symbol'],'get'),true);
if(!$data || !isset($data['data']) || empty($data['data']))
{
var_dump($data);exit;
}else {
$data1 = $data['data'];
$first = $data1[0];
$rate_update = [
'open' => $first['open'],
'close' => $first['close'],
'low' => $first['low'],
'high' => $first['high'],
'usdt' => $first['close'],
'rmb' => $first['close']*6.4,
];
$rate_update['increase'] = sprintf('%.4f',($rate_update['close']-$rate_update['open'])/$rate_update['open']);
Db::name("app_rate")->where("symbol",$release['symbol'])->update($rate_update);
Db::name("app_currency")->where("suffix",$release['symbol'])->update(['exchange'=>$rate_update['close']]);
// unset($data1[0]);//去掉最新一条
$datas = array_column($data1, 'id');
array_multisort($datas, SORT_ASC, $data1);
$last_kline = Db::name("bb_k_24h")->where("symbol",$release['symbol'])->order("ts desc")->find();
$insert = [];
foreach ($data1 as $key => $value) {
if(empty($last_kline)){
$insert[] = [
'symbol' => $release['symbol'],
'ts' => $value['id'],
'open' => $rate['close'],
'close' => $rate['close'],
'low' => $rate['close'],
'high' => $rate['close'],
'vol' => 0,
'count' => 0,
];
}elseif($last_kline['ts'] < $value['id']){
$insert[] = [
'symbol' => $release['symbol'],
'ts' => $value['id'],
'open' => $value['open'],
'close' => $value['close'],
'low' => $value['low'],
'high' => $value['high'],
'vol' => $value['vol'],
'count' => $value['count'],
];
}
}
if(!empty($insert))
{
Db::name('bb_k_24h')->insertAll($insert);
echo "24h";
}
}
}else{
$redis = getRedis();
$time_str = strtotime(date("Y-m-d H:i"));
$key = $rate['symbol'].'-'.$time_str;
$now_price = $redis->get($key);
$key2 = $rate['symbol'].'-'.($time_str-60);
$befor_price = $redis->get($key2);
// var_dump($redis->get("nearusdt"));exit;
//1分钟
$last_kline = Db::name("bb_k_1min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$last_time = $time_str-0;
if(empty($last_kline)){
if($rate['open']>$rate['close']){
$low = $rate['close'];
$high = $rate['open'];
}else{
$low = $rate['open'];
$high = $rate['close'];
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $last_time,
'open' => $rate['open'],
'close' => $rate['close'],
'low' => $low,
'high' => $high,
'vol' => 0,
'count' => 0,
];
Db::name("bb_k_1min")->insert($insert);
}else{
if($last_time>$last_kline['ts']){
if($befor_price){
if($last_kline['vol']){
$vol = sprintf("%.4f",$last_kline['vol']/2 + rand(1000, $last_kline['vol']*1000000)/1000000);
}else{
$vol = rand(100, 999);
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $last_time,
'open' => $last_kline['close'],
'close' => $befor_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => $vol,
'count' => rand(1, 10),
];
}else{
$close = sprintf("%.4f",rand($buy_price*10000, $sell_price*10000)/10000);
$insert = [
'symbol' => $release['symbol'],
'ts' => $last_time,
'open' => $last_kline['close'],
'close' => $new_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => rand(100, 999),
'count' => rand(1, 10),
];
}
$insert['low'] = $insert['low']>$insert['open']?$insert['open']:$insert['low'];
$insert['high'] = $insert['high']<$insert['open']?$insert['open']:$insert['high'];
Db::name("bb_k_1min")->insert($insert);
echo "1min";
}
}
//5fen
$last_kline = Db::name("bb_k_5min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$k5 = $last_kline;
$kline_time = $last_kline['ts']+300;
$last_time = $time_str-0;
if(empty($last_kline)){
$ts = $last_time-($last_time%300);
if($rate['open']>$rate['close']){
$low = $rate['close'];
$high = $rate['open'];
}else{
$low = $rate['open'];
$high = $rate['close'];
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $ts,
'open' => $rate['open'],
'close' => $rate['close'],
'low' => $low,
'high' => $high,
'vol' => 0,
'count' => 0,
];
Db::name("bb_k_5min")->insert($insert);
}elseif($last_time>=$kline_time){
if($befor_price){
if($last_kline['vol']){
$vol = sprintf("%.4f",$last_kline['vol']/2 + rand(1000, $last_kline['vol']*1000000)/1000000);
}else{
$vol = rand(100, 999);
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $befor_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => $vol,
'count' => rand(10, 20),
];
}else{
$close = sprintf("%.4f",rand($buy_price*10000, $sell_price*10000)/10000);
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $new_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => rand(500, 3000),
'count' => rand(10, 20),
];
}
$insert['low'] = $insert['low']>$insert['open']?$insert['open']:$insert['low'];
$insert['high'] = $insert['high']<$insert['open']?$insert['open']:$insert['high'];
Db::name("bb_k_5min")->insert($insert);
echo "5min";
}
//15
$last_kline = Db::name("bb_k_15min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$k15 = $last_kline;
$kline_time = $last_kline['ts']+900;
$last_time = $time_str-0;
if(empty($last_kline)){
$ts = $last_time-($last_time%900);
if($rate['open']>$rate['close']){
$low = $rate['close'];
$high = $rate['open'];
}else{
$low = $rate['open'];
$high = $rate['close'];
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $ts,
'open' => $rate['open'],
'close' => $rate['close'],
'low' => $low,
'high' => $high,
'vol' => 0,
'count' => 0,
];
Db::name("bb_k_15min")->insert($insert);
}elseif($last_time>=$kline_time){
if($befor_price){
if($last_kline['vol']){
$vol = sprintf("%.4f",$last_kline['vol']/2 + rand(1000, $last_kline['vol']*1000000)/1000000);
}else{
$vol = rand(100, 999);
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $befor_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => $vol,
'count' => rand(20, 50),
];
}else{
$close = sprintf("%.4f",rand($buy_price*10000, $sell_price*10000)/10000);
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $new_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => rand(3000, 8000),
'count' => rand(20, 50),
];
}
$insert['low'] = $insert['low']>$insert['open']?$insert['open']:$insert['low'];
$insert['high'] = $insert['high']<$insert['open']?$insert['open']:$insert['high'];
Db::name("bb_k_15min")->insert($insert);
echo "15min";
}
//30
$last_kline = Db::name("bb_k_30min")->where("symbol",$release['symbol'])->order("ts desc")->find();
$k30 = $last_kline;
$kline_time = $last_kline['ts']+1800;
$last_time = $time_str-0;
if(empty($last_kline)){
$ts = $last_time-($last_time%1800);
if($rate['open']>$rate['close']){
$low = $rate['close'];
$high = $rate['open'];
}else{
$low = $rate['open'];
$high = $rate['close'];
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $ts,
'open' => $rate['open'],
'close' => $rate['close'],
'low' => $low,
'high' => $high,
'vol' => 0,
'count' => 0,
];
Db::name("bb_k_30min")->insert($insert);
}elseif($last_time>=$kline_time){
if($befor_price){
if($last_kline['vol']){
$vol = sprintf("%.4f",$last_kline['vol']/2 + rand(1000, $last_kline['vol']*1000000)/1000000);
}else{
$vol = rand(100, 999);
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $befor_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => $vol,
'count' => rand(50, 100),
];
}else{
$close = sprintf("%.4f",rand($buy_price*10000, $sell_price*10000)/10000);
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $new_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => rand(8000, 20000),
'count' => rand(50, 100),
];
}
$insert['low'] = $insert['low']>$insert['open']?$insert['open']:$insert['low'];
$insert['high'] = $insert['high']<$insert['open']?$insert['open']:$insert['high'];
Db::name("bb_k_30min")->insert($insert);
echo "30min";
}
//60
$last_kline = Db::name("bb_k_1h")->where("symbol",$release['symbol'])->order("ts desc")->find();
$k60 = $last_kline;
$kline_time = $last_kline['ts']+3600;
$last_time = $time_str-0;
if(empty($last_kline)){
$ts = $last_time-($last_time%3600);
if($rate['open']>$rate['close']){
$low = $rate['close'];
$high = $rate['open'];
}else{
$low = $rate['open'];
$high = $rate['close'];
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $ts,
'open' => $rate['open'],
'close' => $rate['close'],
'low' => $low,
'high' => $high,
'vol' => 0,
'count' => 0,
];
Db::name("bb_k_1h")->insert($insert);
}elseif($last_time>=$kline_time){
if($befor_price){
if($last_kline['vol']){
$vol = sprintf("%.4f",$last_kline['vol']/2 + rand(1000, $last_kline['vol']*1000000)/1000000);
}else{
$vol = rand(100, 999);
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $befor_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => $vol,
'count' => rand(50, 100),
];
}else{
$close = sprintf("%.4f",rand($buy_price*10000, $sell_price*10000)/10000);
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $new_price,
'low' => $buy_price,
'high' => $sell_price,
'vol' => rand(8000, 20000),
'count' => rand(50, 100),
];
}
$insert['low'] = $insert['low']>$insert['open']?$insert['open']:$insert['low'];
$insert['high'] = $insert['high']<$insert['open']?$insert['open']:$insert['high'];
Db::name("bb_k_1h")->insert($insert);
echo "60min";
}
//1day
$last_kline = Db::name("bb_k_24h")->where("symbol",$release['symbol'])->order("ts desc")->find();
$kline_time = $last_kline['ts']+86400;
$last_time = $time_str-0;
if(empty($last_kline)){
$ts = $last_time-($last_time%86400);
if($rate['open']>$rate['close']){
$low = $rate['close'];
$high = $rate['open'];
}else{
$low = $rate['open'];
$high = $rate['close'];
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $ts,
'open' => $rate['open'],
'close' => $rate['close'],
'low' => $low,
'high' => $high,
'vol' => 0,
'count' => 0,
];
Db::name("bb_k_24h")->insert($insert);
}elseif($last_time>=$kline_time){
if($befor_price){
if($last_kline['vol']){
$vol = sprintf("%.4f",$last_kline['vol']/2 + rand(1000, $last_kline['vol']*1000000)/1000000);
}else{
$vol = rand(100, 999);
}
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $last_kline['close'],
'low' => $last_kline['close'],
'high' => $last_kline['close'],
'vol' => $vol,
'count' => rand(1000, 2000),
];
}else{
$close = sprintf("%.4f",rand($buy_price*10000, $sell_price*10000)/10000);
$insert = [
'symbol' => $release['symbol'],
'ts' => $kline_time,
'open' => $last_kline['close'],
'close' => $last_kline['close'],
'low' => $last_kline['close'],
'high' => $last_kline['close'],
'vol' => rand(20000, 100000),
'count' => rand(1000, 2000),
];
}
$insert['low'] = $insert['low']>$insert['open']?$insert['open']:$insert['low'];
$insert['high'] = $insert['high']<$insert['open']?$insert['open']:$insert['high'];
Db::name("bb_k_24h")->insert($insert);
Db::name("app_rate")->where("symbol",$release['symbol'])->update(['open'=>$insert['close'],'close'=>$insert['close'],'low'=>$insert['close'],'high'=>$insert['close'],'increase'=>0,'amount'=>0]);
echo "24h";
}else{
//跟新今日K线
if($befor_price){
$close = $befor_price;
}else{
$close = sprintf("%.4f",rand($buy_price*10000, $sell_price*10000)/10000);
}
$update = array(
"close" => $close,
);
if($last_kline['low'] > $close){
$update['low'] = $close;
}
if($last_kline['high'] < $close){
$update['high'] = $close;
}
Db::name("bb_k_24h")->where("id",$last_kline['id'])->update($update);
}
if($now_price){
$rate_update = [
"close" => $now_price,
];
if($now_price > $rate['high']){
$rate_update['high'] = $now_price;
if($k5){
Db::name("bb_k_5min")->where("id",$k5['id'])->update(['high'=>$now_price]);
}
if($k15){
Db::name("bb_k_15min")->where("id",$k15['id'])->update(['high'=>$now_price]);
}
if($k30){
Db::name("bb_k_30min")->where("id",$k30['id'])->update(['high'=>$now_price]);
}
if($k60){
Db::name("bb_k_1h")->where("id",$k60['id'])->update(['high'=>$now_price]);
}
}
if($now_price < $rate['low']){
$rate_update['low'] = $now_price;
if($k5){
Db::name("bb_k_5min")->where("id",$k5['id'])->update(['low'=>$now_price]);
}
if($k15){
Db::name("bb_k_15min")->where("id",$k15['id'])->update(['low'=>$now_price]);
}
if($k30){
Db::name("bb_k_30min")->where("id",$k30['id'])->update(['low'=>$now_price]);
}
if($k60){
Db::name("bb_k_1h")->where("id",$k60['id'])->update(['low'=>$now_price]);
}
}
$rate_update['increase'] = sprintf('%.4f',($rate_update['close']-$rate['open'])/$rate['open']);
$rate_update['amount'] = $rate['amount']+rand(10,100);
Db::name("app_rate")->where("symbol",$release['symbol'])->update($rate_update);
Db::name("app_currency")->where("suffix",$release['symbol'])->update(['exchange'=>$rate_update['close']]);
echo "更新最新价:".$rate_update['close'];
}else{
$now_price = $new_price;
$rate_update = [
"close" => $now_price,
];
if($now_price > $rate['high']){
$rate_update['high'] = $now_price;
if($k30){
Db::name("bb_k_30min")->where("id",$k30['id'])->update(['high'=>$now_price]);
}
if($k60){
Db::name("bb_k_1h")->where("id",$k60['id'])->update(['high'=>$now_price]);
}
}
if($now_price < $rate['low']){
$rate_update['low'] = $now_price;
if($k30){
Db::name("bb_k_30min")->where("id",$k30['id'])->update(['low'=>$now_price]);
}
if($k60){
Db::name("bb_k_1h")->where("id",$k60['id'])->update(['low'=>$now_price]);
}
}
$rate_update['increase'] = sprintf('%.4f',($rate_update['close']-$rate['open'])/$rate['open']);
$rate_update['amount'] = $rate['amount']+rand(10,100);
Db::name("app_rate")->where("symbol",$release['symbol'])->update($rate_update);
Db::name("app_currency")->where("suffix",$release['symbol'])->update(['exchange'=>$rate_update['close']]);
echo "更新定义价:".$rate_update['close'];
}
}
echo "success";
}
//4位小数的随机数
public function randomFloat($min = 0, $max = 10 , $localnum = 4)
{
if($localnum == 4) {
if ($max - $min <= 0.0002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.0001);
$num = $min + $rand;
$number = sprintf("%.4f", $num);
if($number == $min){
$number += 0.0001;
}
}else if($localnum == 5){
if ($max - $min <= 0.00002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.00001);
$num = $min + $rand;
$number = sprintf("%.5f", $num);
if($number == $min){
$number += 0.00001;
}
}else if($localnum == 6){
if ($max - $min <= 0.000002) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.000001);
$num = $min + $rand;
$number = sprintf("%.6f", $num);
if($number == $min){
$number += 0.000001;
}
}else if($localnum == 2){
if ($max - $min <= 0.02) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.01);
$num = $min + $rand;
$number = sprintf("%.2f", $num);
if($number == $min){
$number += 0.01;
}
}else if($localnum == 3){
if ($max - $min <= 0.001) {
return 0;
}
$rand = mt_rand() / mt_getrandmax() * ($max - $min-0.001);
$num = $min + $rand;
$number = sprintf("%.3f", $num);
if($number == $min){
$number += 0.001;
}
}
return $number;
}
}
+1489
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+923
View File
@@ -0,0 +1,923 @@
<?php
namespace app\api\controller;
use app\api\library\exchange\Binance;
use app\common\controller\Api;
use app\common\library\Ems;
use app\common\library\Sms;
use fast\Random;
use think\Validate;
use think\Config;
use think\Db;
use app\api\library\exchange\Huobi;
use function fast\e;
/**
* 量化任务接口
*/
class Tasklh extends Api
{
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['*'];
public function update_coin(){
$t = time();
$coin = Db::name('app_rate a')
->where("bb_type",1)
->field('a.*')
->select();
$rate = 6.45;
echo "update---";
$url = 'https://api.huobi.pro/market/tickers';
$data = json_decode(http_curl($url),true);
$data_forex = json_decode(http_curl("http://f-test.js-stock.top/getkine?symbol=XAUUSD&cmd=quote&key=jssj2023keykey123"), true);
if($data['status'] != "ok"){
echo "获取失败";exit;
}
foreach ($coin as $key=>$value)
{
foreach ($data['data'] as $k=>$v)
{
if($value['symbol'] == $v['symbol']){
$update = [
'open' => $v['open'],
'close' => $v['close'],
'high' => $v['high'],
'low' => $v['low']
];
$update['increase'] = sprintf('%.4f',($update['close']-$update['open'])/$update['open']);
$update['updatetime'] = time();
$update['price'] = $update['close'];
//获取交易经度 ai用
// $url1 = 'https://api.huobi.pro/v1/common/symbols';
// $data1 = json_decode(http_curl($url1),true);
// if(isset($data1['status']) && $data1['status'] == 'ok')
// {
// $datarr = array_column($data1['data'], 'amount-precision','symbol');
// }
// $update['precision'] = $datarr[$value['symbol']];
Db::name('app_ai_coin')->where('id',$value['id'])->update($update);
//修改rate
$tradedata = $v;
$updatearr = [
'amount' => $tradedata['amount'],
'open' => $tradedata['open'],
'close' => $tradedata['close'],
'high' => $tradedata['high'],
'low' => $tradedata['low'],
'usdt' => $tradedata['close'],
'rmb' => $tradedata['close']*$rate,
'updatetime' => time()
];
$updatearr['increase'] = sprintf("%.4f",
($updatearr['close']-$updatearr['open'])/$updatearr['open']);
Db::name('app_rate')->where('symbol',$value['symbol'])->update($updatearr);
//修改curr
Db::name("app_currency")->where("suffix",$value['symbol'])->update(['exchange'=>$updatearr['close']]);
echo $value['symbol'].'---';
}
}
if($value['symbol'] == "xauusd"){
$update = [
'open' => floatval($data_forex['open']),
'close' => floatval($data_forex['close']),
'high' => floatval($data_forex['high']),
'low' => floatval($data_forex['low']),
];
$update['increase'] = sprintf('%.4f',($update['close']-$update['open'])/$update['open']);
$update['updatetime'] = time();
$update['price'] = $update['close'];
Db::name('app_ai_coin')->where('id',$value['id'])->update($update);
//修改rate
$tradedata = $data_forex;
$updatearr = [
'amount' => floatval($tradedata['bid']),
'open' => floatval($tradedata['open']),
'close' => floatval($tradedata['close']),
'high' => floatval($tradedata['high']),
'low' => floatval($tradedata['low']),
'usdt' => floatval($tradedata['close']),
'rmb' => floatval($tradedata['close'])*$rate,
'updatetime' => time()
];
$updatearr['increase'] = sprintf("%.4f",
($updatearr['close']-$updatearr['open'])/$updatearr['open']);
Db::name('app_rate')->where('symbol',$value['symbol'])->update($updatearr);
//修改curr
Db::name("app_currency")->where("suffix",$value['symbol'])->update(['exchange'=>$updatearr['close']]);
echo $value['symbol'].'---';
}
}
echo "执行时长:".(time()-$t)."";
}
//同步火币价格
// public function update_coin()
// {
// $t = time();
// $coin = Db::name('app_ai_coin a')
// ->field('a.*')
// ->where('a.status','1')
// ->select();
// $rate = 6.45;
// echo "update---";
// foreach ($coin as $key=>$value)
// {
// $url1 = 'https://api.huobi.pro/v1/common/symbols';
// $data1 = json_decode(http_curl($url1),true);
// if(isset($data1['status']) && $data1['status'] == 'ok')
// {
// $datarr = array_column($data1['data'], 'amount-precision','symbol');
// }
// $url = 'https://api.huobi.pro/market/history/kline?period=1day&size=1&symbol='.$value['symbol'];
// $data = json_decode(http_curl($url),true);
// if(isset($data['status']) && $data['status'] == 'ok')
// {
// $update = [
// 'open' => $data['data'][0]['open'],
// 'close' => $data['data'][0]['close'],
// 'high' => $data['data'][0]['high'],
// 'low' => $data['data'][0]['low']
// ];
// $update['increase'] = sprintf('%.4f',($update['close']-$update['open'])/$update['open']);
// $update['updatetime'] = time();
// $update['price'] = $update['close'];
// $update['precision'] = $datarr[$value['symbol']];
// Db::name('app_ai_coin')->where('id',$value['id'])->update($update);
// //修改rate
// $tradedata = $data['data'][0];
// $updatearr = [
// 'amount' => $tradedata['amount'],
// 'open' => $tradedata['open'],
// 'close' => $tradedata['close'],
// 'high' => $tradedata['high'],
// 'low' => $tradedata['low'],
// 'usdt' => $tradedata['close'],
// 'rmb' => $tradedata['close']*$rate,
// 'updatetime' => time()
// ];
// $updatearr['increase'] = sprintf("%.4f",
// ($updatearr['close']-$updatearr['open'])/$updatearr['close']);
// Db::name('app_rate')->where('symbol',$value['symbol'])->update($updatearr);
// //修改curr
// Db::name("app_currency")->where("suffix",$value['symbol'])->update(['exchange'=>$updatearr['close']]);
// echo $value['symbol'].'---';
// }
// }
// echo "执行时长:".(time()-$t)."秒";
// }
//开启策略
public function open_strategy()
{
$strategyid = $this->request->get('strategy_id');
if(!$strategyid)
{
echo "error id";exit;
}
$redis = getRedis();
$running = $redis->get('strategyo-'.$strategyid);
if($running) {
echo "运行未完成";exit;
}
$redis->set('strategyo-'.$strategyid, time(), 60);
//查询任务
$tasks = Db::name('app_ai_task')
->where('strategy_id',$strategyid)->find();
if(empty($tasks)) echo '任务未创建';
$msg = '策略-'.$strategyid.'||';
$strategy = Db::name('app_ai_strategy')
->where('id',$strategyid)
->where('status','1')->find();
if(empty($strategy))
{
$msg .= '未查询到策略'.$strategyid;
$result = del_bt_cron($strategyid);
if(isset($result['status']) && $result['status'] === true)
{
$msg .= '策略-'.$strategyid.'暂停成功---';
}else{
$msg .= '策略-'.$strategyid.'暂停失败---';
}
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
$coin = Db::name('app_ai_coin a')
->field('a.*')
->where('a.id',$strategy['coin_id'])
->find();
$strategy_order = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->order('id','desc')
->find();
//获取分钟K线
$url = 'https://api.huobi.pro/market/history/kline?period=1min&size=10&symbol='.$coin['symbol'];
$data = json_decode(http_curl($url),true);
$prices = [];
$nowtime1 = strtotime(date('Y-m-d H:i:00'));
if(isset($data['status']) && $data['status'] == 'ok') {
foreach ($data['data'] as $k => $val) {
if($val['id'] >= $nowtime1) continue; // 当前分钟线不算
$prices[] = [
'coin_id' => $coin['id'],
'coinname' => $coin['symbol'],
'get_id' => $val['id'],
'open' => $val['open'],
'close' => $val['close'],
'high' => $val['high'],
'low' => $val['low'],
'increase' => sprintf('%.4f', ($val['close'] - $val['open']) / $val['open']),
'createtime' => time(),
];
}
$last_names = array_column($prices,'get_id');
array_multisort($last_names,SORT_DESC,$prices);
}else{
$msg .= '火币接口异常0'.var_dump($data);
$redis->set('strategyo-' . $strategy['id'], false);
echo $msg;
exit;
}
$coindata = json_decode(http_curl('https://api.huobi.pro/market/trade?symbol='.$coin['symbol']),true);
if(!isset($coindata['status']) || $coindata['status'] != 'ok')
{
$msg .= '火币接口异常'.var_dump($data);
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
}
$newprice = $coindata['tick']['data'][0]['price'];
$orderid = $coindata['tick']['data'][0]['trade-id'];
$nowtimes = time();
$lasttime = $prices[0]['get_id'];
$difftimes = $nowtimes - $lasttime;
echo '最新价格时间:'.date("Y-m-d H:i:s",$lasttime).'--';
if($difftimes > 120)
{
$msg .= '价格未同步,'.$coin['coinname'].':时间差'.$difftimes;
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
}
$comein = false;
$msg .= 'a';
$nowuser = Db::name('user')->where('id',$strategy['user_id'])->find();
//判断是不是首单
if(empty($strategy_order) || $strategy_order['type'] == '2')
{
$msg .= 'b';
//根据往期判断入场时机
//最高点附近不入、连续下跌不入、连续上涨不入
$fall = 0;
$rise = 0;
foreach ($prices as $k => $val)
{
if($val['increase'] < 0) $fall += 1;
else $rise += 1;
if(($fall - $rise >=2) && $rise > 0 && $rise<2)
{
$comein = true;
break;
}
//连续涨或连续跌
if($rise >=2 || ($fall >= 2 && $rise < 1)) break;
if($k == 0 && $fall >=1) break; //第一根是跌的情况
}
if($strategy['is_now'] == '1'){
$comein = true;
}
if(!$comein){
$msg .= '未达入场条件--'.date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
if($strategy['in_price'] > 0 && $newprice > $strategy['in_price'])
{
$msg .= '未达设置的入场价格:now-'.$newprice.'-set-'.$strategy['in_price'].'--'.date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
}
$num = sprintf('%.6f',$strategy['first_num']/$newprice);
$dou = pow(10,$coin['precision']);
//发起交易所接口---- 判断信誉值够不够!!!!!!!!
$user_usdt = Db::name("app_currency_user")->where("user_id",$strategy['user_id'])->where("curr_id",1)->find();
if($user_usdt['num_lh'] < $strategy['first_num']){
$msg .= '余额不足,当前余额'.$user_usdt['num_lh'].'--'.date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
$detailed = [
'user_id' => $strategy['user_id'],
'curr_id' => '1',
'price' => $strategy['first_num'],
'cart' => '2',
'type' => '2',
'description' => '量化入场',
'createtime' => time(),
'before_num' => $user_usdt['num_lh'],
'after_num' => $user_usdt['num_lh']-$strategy['first_num']
];
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$user_usdt['num_lh']-$strategy['first_num']]);
Db::name("app_detailed_lh")->insert($detailed);
$order = [
'user_id' => $strategy['user_id'],
'coin_id' => $coin['id'],
'strategy_id' => $strategy['id'],
'type' => '1',
'order_sn' => $orderid,
'num' => $num,
'amount' => $strategy['first_num'],
'price' => $newprice,
'fee' => sprintf('%.8f', $num * 0.002),
'bc_time' => 0,
'createtime' => time(),
];
if(empty($strategy_order)) $order['strategy_code'] = 1;
else $order['strategy_code'] = $strategy_order['strategy_code'] + 1;
//需要扣除手续费后 根据精度算出真实持仓数量
$ccnums = intval(($order['num']- $order['fee'])*pow(10,8))/pow(10,8);
$ccprices = intval($order['amount']/$ccnums*pow(10,8))/pow(10,8);
Db::name('app_ai_strategy_order')->insert($order);
Db::name('app_ai_strategy')
->where('id',$strategy['id'])->update(['cc_price'=>$ccprices,'cc_num'=>$ccnums,
'cc_amount'=>$order['amount'],'updatetime'=>time()]);
$msg .= '策略:'.$strategy['id'].'开始量化---'.date("Y-m-d H:i:s");
}else if($strategy_order['type'] == '1')
{
$msg .= 'c';
//判断补仓还是卖出
// $newprice = 52405.84;
if($newprice > $strategy_order['price']) { //涨 平仓
//判断是否达平仓条件
//止盈比例
$percent = $strategy['zy_percent'];
if($strategy['cc_price'] > 0) {
$nowpercent = sprintf("%.4f", ($newprice - $strategy['cc_price']) / $strategy['cc_price']);
}else{
$nowpercent = 0;
}
//判断是否是最高点---
//达止盈条件,含回调
//盈利最大化,防止持续上涨,盈利不足
$comein0 = false;
$fall = $rise = 0;
foreach ($prices as $k => $val)
{
if($val['increase'] < 0) $fall += 1;
else $rise += 1;
//连续涨或连续跌
if($rise >= $fall) break;
if($k == 0 && $rise >=1) break; //第一根是涨的情况
//回调是否取当前这分钟K线跌幅0.3%???
if($k == 0 && $val['increase'] < 0 && abs($val['increase']) >= $strategy['zy_ht'])
{
$comein0 = true;
break;
}else if($fall >=2){
$comein0 = true;
break;
}
}
if($nowpercent >= $percent && $comein0)
{
$comein = true;
}
echo '条件:1-'.$nowpercent.'|2-'.$percent.'|3-'.$prices[0]['increase'].'|4-'.$prices[0]['get_id'];
if($comein) { //达到止盈条件,平仓
//总持仓数量
$sumnum = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('num');
//发起交易所接口----
$num = $sumnum;
$outamount = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('amount');
//总手续费
$sumfee = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('fee');
$dou = pow(10,$coin['precision']);
$newnum = intval(($num-$sumfee)*$dou)/$dou;
$newnum1 = intval($num*$dou)/$dou;
$amount = sprintf('%.6f',$newnum*$newprice);
$income = sprintf('%.6f',$amount - $outamount);
if($income < 0 ) {
$msg .= '-策略:' . $strategy['id'] . '平仓失败,实际交易价格不足-' . $newprice . ',盈亏:
' . $income . '交易数量-'.$newnum.'--' . date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
//扣除信誉值
$kouchu = sprintf('%.4f',Config::get('site.xinyu_percent')*$income);
$currency = Db::name('app_currency_user')
->where('user_id',$strategy['user_id'])
->where('curr_id','2')->find();
$diffnum = sprintf('%.4f',$currency['num_lh'] - $kouchu);
if($diffnum < 0)
{
$msg .= '-策略:'.$strategy['id'].'平仓失败,信誉值不足:余额-'.$currency['num'].',需扣除信誉值:
'.$kouchu.'---'.date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
$order = [
'user_id' => $strategy['user_id'],
'coin_id' => $coin['id'],
'strategy_id' => $strategy['id'],
'type' => '2',
'order_sn' => $orderid,
'num' => $num,
'amount' => $amount,
'price' => $newprice,
'fee' => sprintf('%.4f', $amount * 0.0012),
'bc_time' => 0,
'createtime' => time(),
'strategy_code' => $strategy_order['strategy_code'],
'income' => $income,
];
$user_usdt = Db::name("app_currency_user")->where("user_id", $strategy['user_id'])->where("curr_id",1)->find();
$detailed[] = [
'user_id' => $strategy['user_id'],
'curr_id' => '1',
'price' => $amount,
'cart' => '1',
'type' => '2',
'description' => '量化卖出',
'createtime' => time(),
'before_num' => $user_usdt['num_lh'],
'after_num' => $user_usdt['num_lh']+$amount
];
$detailed[] = [
'user_id' => $strategy['user_id'],
'curr_id' => '2',
'price' => $kouchu,
'cart' => '2',
'type' => '2',
'description' => '扣取信誉值',
'createtime' => time(),
'before_num' => $currency['num_lh'],
'after_num' => $diffnum
];
Db::startTrans();
try {
//收支操作
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$user_usdt['num_lh']+$amount]);
Db::name('app_currency_user')->where('id',$currency['id'])->update(['num_lh'=>$diffnum]);
Db::name('app_ai_strategy_order')->insert($order);
Db::name('app_ai_strategy')
->where('id',$strategy['id'])->update(['cc_price'=>0,'cc_num'=>0,'cc_amount'=>0,'updatetime'=>time()]);
if($strategy['type'] == '1'){ //单次循环暂停
Db::name('app_ai_strategy')
->where('id',$strategy['id'])
->update(['status'=>'0','updatetime'=>time()]);
}
//上级反信誉值
$users = Db::name('user')->where('id',$strategy['user_id'])->find();
if($users['lh_act'] == 1){
$usersarr = array_filter(array_reverse( explode('|',$users['path'])));
$level = 0;
$ai_push_profit = Config::get("site.ai_push_profit");//直推
$level_arr = Db::name("app_ai_grade")->field("id,name,level,team_prize")->where("team_prize",">",0)->select();
$team_prize = 0;
foreach ($usersarr as $ks => $vals)
{
if(!is_numeric($vals) || empty($vals)) continue;
if($vals == 1) continue;
if($vals == $users['id']) continue;
$usera = Db::name('user')->where('id',$vals)->find();
$currencys = Db::name('app_currency_user')
->where('user_id',$usera['id'])
->where('curr_id','2')->find();
//先算直推
if($ks == 2){
$push_price = sprintf("%.6f",$kouchu*$ai_push_profit);
$detailed[] = array(
'user_id' => $usera['id'],
'curr_id' => '2',
'price' => $push_price,
'cart' => '1',
'type' => '3',
'description' => '直推获取信誉值',
'createtime' => time(),
'before_num' => $currencys['num_lh'],
'after_num' => $currencys['num_lh']+$push_price,
);
Db::name("app_currency_user")->where("id",$currencys['id'])->update(['num_lh'=>$currencys['num_lh']+$push_price]);
continue;
}
if($usera['level_id'] == 1 || $usera['level_id']<=$level){
continue;
}
// 团队将
foreach ($level_arr as $kk => $vv) {
if($vv['id'] == $usera['level_id']){
$team_price = sprintf("%.6f",$kouchu*($vv['team_prize']-$team_prize)/100);
$detailed[] = array(
'user_id' => $usera['id'],
'curr_id' => '2',
'price' => $team_price,
'cart' => '1',
'type' => '4',
'description' => '团队获取信誉值',
'createtime' => time(),
'before_num' => $currencys['num_lh'],
'after_num' => $currencys['num_lh']+$team_price,
);
Db::name("app_currency_user")->where("id",$currencys['id'])->update(['num_lh'=>$currencys['num_lh']+$team_price]);
$level = $usera['level_id'];
$team_prize = $vv['team_prize'];
}
}
}
}
Db::name('app_detailed_lh')->insertAll($detailed);
//真实发起交易----
Db::commit();
$msg .= '已平仓,盈利'.$income.'---'.date("Y-m-d H:i:s");
} catch (Exception $e) {
Db::rollback();
$msg .= '数据库操作失误2';
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
}else{
$msg .= '未达平仓条件---'.date("Y-m-d H:i:s");
}
}else{
$msg .= 'd';
$bcjson = json_decode($strategy['bcjson'],true);
//是否停止补仓
if($strategy['pc_status'] == '1')
{
$msg .= '已设置停止补仓---'.date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
}
//判断是不是达到补仓条件
//已补仓次数
$newpc = Db::name('app_ai_strategy_order')
->where('strategy_id', $strategy['id'])
->where('strategy_code', $strategy_order['strategy_code'])
->order('bc_time', 'desc')
->find();
$bctime = $newpc['bc_time'];
if ($bctime >= $strategy['num']) //达到最大补仓次数
{
$msg .= '已达最大补仓次数---'.date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
$bctimes = (string)($bctime + 1);
$percent = $bcjson[$bctimes];
if($strategy['cc_price'] > 0) {
$nowpercent = sprintf("%.4f", abs($newprice - $strategy['cc_price']) / $strategy['cc_price']);
}else{
$nowpercent = 0;
}
//达补仓条件,并且最新有回调
if ($nowpercent >= $percent && $prices[0]['increase'] > 0 && $prices[0]['increase'] > $strategy['bc_ht']) {
$comein = true;
}
if($comein) { //达到补仓条件
//是否倍投
if ($strategy['is_double'])
$amount = $strategy_order['amount'] * 2;
else $amount = $strategy_order['amount'];
//发起交易所接口----
$num = sprintf('%.6f', $amount / $newprice);
$dou = pow(10,$coin['precision']);
$user_usdt = Db::name("app_currency_user")->where("user_id",$strategy['user_id'])->where("curr_id",1)->find();
if($user_usdt['num_lh'] < $amount){
$msg .= '余额不足,当前余额'.$user_usdt['num_lh'].'--'.date("Y-m-d H:i:s");
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
}
$detailed = [
'user_id' => $strategy['user_id'],
'curr_id' => '1',
'price' => $amount,
'cart' => '2',
'type' => '2',
'description' => '量化补仓',
'createtime' => time(),
'before_num' => $user_usdt['num_lh'],
'after_num' => $user_usdt['num_lh']-$amount
];
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$user_usdt['num_lh']-$amount]);
Db::name("app_detailed_lh")->insert($detailed);
$order = [
'user_id' => $strategy['user_id'],
'coin_id' => $coin['id'],
'strategy_id' => $strategy['id'],
'type' => '1',
'order_sn' => $orderid,
'num' => $num,
'amount' => $amount,
'price' => $newprice,
'fee' => sprintf('%.8f', $num * 0.002),
'bc_time' => $bctimes,
'createtime' => time(),
'strategy_code' => $strategy_order['strategy_code'],
];
Db::name('app_ai_strategy_order')->insert($order);
//更新持仓均价
$allamount = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('amount');
$allnum = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('num');
$allfee = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('fee');
$ccnums = intval(($allnum - $allfee)*pow(10,8))/pow(10,8);
$ccprices = intval($allamount/$ccnums*pow(10,8))/pow(10,8);
Db::name('app_ai_strategy')
->where('id',$strategy['id'])->update(['cc_price'=>$ccprices,'cc_num'=>$ccnums,
'cc_amount'=>$allamount,'updatetime'=>time()]);
$msg .= '策略:'.$strategy['id'].'已补仓'.$bctimes.'次---'.date("Y-m-d H:i:s");
}else{
$msg .= '策略:'.$strategy['id'].',未达补仓条件,补仓次数'.$bctimes.',持仓均价:'.$strategy['cc_price'].
',最新价格'.$newprice.',亏损比例'.$nowpercent.',达补仓比例'.$percent.'回调比例:'.$strategy['bc_ht'].
'目前涨幅比例:'.$prices[0]['increase'].'---'.date("Y-m-d H:i:s");
}
}
}
$redis->set('strategyo-'.$strategyid,"");
echo $msg.date("Y-m-d H:i:s");exit;
}
//定时启动策略
public function start_cron()
{
echo '监听策略状态|-|';
$strategy = Db::name('app_ai_strategy a')
->field('a.*,b.id as task_id')
->join('app_ai_task b','a.id=b.strategy_id','left')
->where('b.id',null)
->where('a.status','1')
->limit(300)
->select();
foreach ($strategy as $key=>$value)
{
$task = Db::name('app_ai_task')
->where('strategy_id',$value['id'])->find();
if($value['status'] == '1' && empty($task))
{
$result = create_bt_cron($value['id']);
if(isset($result['status']) && $result['status'] === true)
{
echo '策略-'.$value['id'].'启动成功---';
}else{
echo '策略-'.$value['id'].'启动失败---';
}
}
}
}
//定时关闭策略
public function close_cron()
{
echo '监听策略状态|-|';
$strategy = Db::name('app_ai_strategy')
->where('status','0')
->select();
foreach ($strategy as $key=>$value)
{
$task = Db::name('app_ai_task')
->where('strategy_id',$value['id'])->find();
if($value['status'] == '0' && !empty($task))
{
$result = del_bt_cron($value['id']);
if(isset($result['status']) && $result['status'] === true)
{
echo '策略-'.$value['id'].'暂停成功---';
}else{
echo '策略-'.$value['id'].'暂停失败---';
}
}
}
}
//计算用户累计收益
public function js_allincome()
{
$today = time() - 120;
$user = Db::name('user a')
->field('a.id,b.updatetime')
->join('app_ai_user_income_all b','a.id=b.user_id','left')
->where('b.updatetime','<',$today)
->whereOr('b.updatetime',null)
->limit(5)
->order('b.updatetime','asc')
->select();
echo 'update-';
foreach ($user as $key=>$value)
{
$valss['id'] = 1;
$jstime = date('Y-m-d');
$jsarr = Db::name('app_ai_user_income')
->where('user_id',$value['id'])
->where('exchange_id',$valss['id'])
->select();
$jsarrs = array_column($jsarr,'id','jstime');
$datas = Db::name('app_ai_strategy_order a')
->field('a.income,a.createtime,a.amount')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$valss['id'])
->where('a.type','2')
->where('a.user_id',$value['id'])
->where('a.income','>',0)
->order('a.id', 'asc')
->select();
$insert = [];
$update = [];
$today = strtotime(date('Y-m-d 00:00:00'));
foreach ($datas as $keys=>$values)
{
$jjtime = date('Y-m-d',$values['createtime']);
if(!isset($jsarrs[$jjtime]))
{
if(!isset($insert[$jjtime])) {
$insert[$jjtime]['income'] = $values['income'];
$insert[$jjtime]['pcnum'] = $values['amount'];
}else {
$insert[$jjtime]['income'] += $values['income'];
$insert[$jjtime]['pcnum'] += $values['amount'];
}
}else
{
if(!isset($update[$jjtime])) {
$update[$jjtime]['income'] = $values['income'];
$update[$jjtime]['pcnum'] = $values['amount'];
}
else {
$update[$jjtime]['income'] += $values['income'];
$update[$jjtime]['pcnum'] += $values['amount'];
}
}
}
if(!empty($insert)){
$insertarr = [];
foreach ($insert as $k => $val)
{
$insertarr[] = [
'user_id' => $value['id'],
'num' => $val['income'],
'jstime' => $k,
'createtime' => time(),
'pcnum' => $val['pcnum'],
'income_per' => sprintf('%.4f',$val['income']/($val['pcnum'] - $val['income'])),
'exchange_id' => $valss['id'],
];
}
Db::name('app_ai_user_income')->insertAll($insertarr);
}
if(!empty($update))
{
foreach ($update as $k=>$val)
{
Db::name('app_ai_user_income')
->where('user_id',$value['id'])
->where('exchange_id',$valss['id'])
->where('jstime',$k)->update(['num'=>$val['income'],
'pcnum' => $val['pcnum'],
'income_per' => sprintf('%.4f',$val['income']/($val['pcnum'] - $val['income'])),
'updatetime'=>time()]);
}
}
$all_num = sprintf('%.6f', Db::name('app_ai_strategy_order a')
->field('a.income,a.createtime')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$valss['id'])
->where('a.type','2')
->where('a.user_id',$value['id'])
->where('a.income','>',0)
->order('a.id', 'desc')->sum('amount'));
$all_income = sprintf('%.6f', Db::name('app_ai_strategy_order a')
->field('a.income,a.createtime')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$valss['id'])
->where('a.type','2')
->where('a.user_id',$value['id'])
->where('a.income','>',0)
->order('a.id', 'desc')->sum('income'));
$all_fee = sprintf('%.6f', Db::name('app_ai_strategy_order a')
->field('a.income,a.createtime')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$valss['id'])
->where('a.type','2')
->where('a.user_id',$value['id'])
->where('a.income','>',0)
->order('a.id', 'desc')->sum('fee'));
if($all_num>0)
$income_per = sprintf('%.4f',$all_income/($all_num-$all_income));
else $income_per = 0;
$allnums = [
'user_id' => $value['id'],
'income' => $all_income,
'fee' => $all_fee,
'income_per' => $income_per,
'createtime' => time(),
'pcnum' => $all_num,
'exchange_id' => $valss['id']
];
$incomeall = Db::name('app_ai_user_income_all')
->where('user_id', $value['id'])
->where('exchange_id',$valss['id'])
->find();
if($incomeall)
{
unset($allnums['createtime']);
$allnums['updatetime'] = time();
Db::name('app_ai_user_income_all')
->where('id',$incomeall['id'])->update($allnums);
}else{
Db::name('app_ai_user_income_all')->insert($allnums);
}
echo '-'.$value['id'].'-';
}
}
/**
* 量化等级计算
*/
public function lh_level_upd()
{
$t = time();
$user = Db::name("user a")->field("a.id,b.level,a.path,a.lh_act")
->join("app_ai_grade b","a.grade_id=b.id","left")
->order("a.updatetime asc")
->limit(50)
->select();
if(empty($user)){
echo "empty";exit;
}
foreach ($user as $key => $value) {
$user_update = array(
"updatetime" => time(),
);
//下一个等级
$next_level = Db::name("app_ai_grade")->where("level",">",$value['level'])->order("level asc")->find();
if(!empty($next_level) && $value['lh_act'] == 1){
//达标升级
$team_num = Db::name("user")->field("id")->where("path","like",$value['path']."%")->where("id","neq",$value['id'])->where("lh_act",1)->count();
if($team_num >= $next_level['team_num']){
$user_update['grade_id'] = $next_level['id'];
}
}
Db::name("user")->where("id",$value['id'])->update($user_update);
}
echo "执行时长:".(time()-$t);
}
}
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use fast\Random;
/**
* Token接口
*/
class Token extends Api
{
protected $noNeedLogin = [];
protected $noNeedRight = '*';
/**
* 检测Token是否过期
*
*/
public function check()
{
$token = $this->auth->getToken();
$tokenInfo = \app\common\library\Token::get($token);
$this->success('', ['token' => $tokenInfo['token'], 'expires_in' => $tokenInfo['expires_in']]);
}
/**
* 刷新Token
*
*/
public function refresh()
{
//删除源Token
$token = $this->auth->getToken();
\app\common\library\Token::delete($token);
//创建新Token
$token = Random::uuid();
\app\common\library\Token::set($token, $this->auth->id, 2592000);
$tokenInfo = \app\common\library\Token::get($token);
$this->success('', ['token' => $tokenInfo['token'], 'expires_in' => $tokenInfo['expires_in']]);
}
}
+881
View File
@@ -0,0 +1,881 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\model\TradeConfig;
use think\worker\Server;
use Workerman\Worker;
use Workerman\Lib\Timer;
use Workerman\Connection\AsyncTcpConnection;
use \Workerman\Autoloader;
use GatewayWorker\Gateway;
use think\Log;
use think\Db;
use think\Exception;
use fast\Random;
use app\common\library\Token;
//use think\console\Input;
//use think\console\Output;
//use think\console\Command;
//心跳间隔5秒
define('HEARTBEAT_TIME', 10);
/**
*交易对K线图数据生成-火币
* 用于实时接收火币K线数据
*/
class TradeKline extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
protected $flag = true;//是否正式环境
protected $huobi_host = '';
protected $server_host = 'ws://api.huobiasia.vip/ws';
protected $host = 'ws://api.huobiasia.vip/ws';
protected $local_host = 'Websocket://0.0.0.0:8686';// 代理监听本地9999端口
private $time_list = [
'1min'=>60, //1分钟
'5min'=>300,//5分钟
'15min'=>900,//15分钟
'30min'=>1800,//30分钟
'60min'=>3600,//1小时
'1day'=>86400,//1天
'1week'=>604800,//1周
'1mon'=>2592000, //1月
//'1year'=>31536000, //1年
];
private $time_lists = ['1min','5min','15min','30min','1day','1week','1mon'];
private $symbol_list = ['market.btcusdt.trade.detail',];
private $all_cons = [];
private $all_symbols = ['btcusdt','ethusdt','ltcusdt','bchusdt','eosusdt'];
//private $all_dic = [];
private $testip = array("192.168.10.234", "192.168.230.1");
private $huobi_id = 0;//连接火币服务器的连接id,防止心跳把火币连接关闭
private $reconnect_num = 0;//与火币服务器的重连次数,超过一定次数重启Worker,目前是10次,windows下无法重启
private $async_message_time = 0;//与火币服务器的消息交互时间,超过一定时间没有消息往来重启Worker,目前是300swindows下无法重启
public function index()
{
// 创建一个Worker监听2345端口,使用http协议通讯
$this->worker = new Worker("websocket://0.0.0.0:8686");
$info = "启动Worker-start:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
$this->saveLog("huobi", $info);
$this->ctrl = [];
$this->historykline = [];
// 启动1个进程对外提供服务
$this->worker->count = 1;
$this->worker->name = 'huobikline';
$this->worker->onWorkerStart = function($worker)
{
$this->onWorkerStart($worker);
};
$this->huobiflag = false;
$this->userdy = [];
// 接收到浏览器发送的数据时回复hello world给浏览器
$this->worker->onMessage = function($connection, $data)
{
$this->onWorkerMessage($connection, $data);
};
Worker::runAll();
}
function onWorkerStart($worker)
{
$info = "启动Worker-start success:".date('Y-m-d H:i:s');
echo "\r\n ".$info;
$this->saveLog("huobi", $info);
// 进程启动后设置一个每秒运行一次的定时器
Timer::add(1, function()use($worker){
$time_now = time();
if(count($worker->connections) > 0) {
$this->saveLog("all", '心跳计时器,count:' . count($worker->connections));
}
foreach($worker->connections as $connection) {
if ($connection->id == $this->huobi_id) {
$this->saveLog("all", '心跳计时器,huobi_id:'.$this->huobi_id);
continue;
}
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔*2,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME * 2) {
$this->saveLog("all", '心跳计时器,心跳超时,cid:'.$connection->id.',now:'.date('Y-m-d H:i:s', $time_now).',lastMessageTime:'.date('Y-m-d H:i:s', $connection->lastMessageTime));
$connection->close();
//unset($this->all_cons[$connection->id]);
}
}
// if ($this->reconnect_num >= 10) {//与火币的连接断开重连超过10次,重启Worker
// $info = "与火币的连接断开重连超过10次,重启Worker:".date('Y-m-d H:i:s');
// echo "\r\n".$info;
// $this->saveLog("huobi", $info);
// Worker::stopAll();
// }
// if ($time_now - $this->async_message_time > 300) {
// $info = "与火币的连接超过300s没有消息交互,重启Worker:".date('Y-m-d H:i:s');
// echo "\r\n".$info;
// $this->saveLog("huobi", $info);
// Worker::stopAll();
// }
//查询控制价格是否有值
$ctrl = Db::name('hb_ctrl')
->where('ts','>=',(time() - 10))
->select();
if($ctrl)
{
$this->ctrl = [];
foreach ($ctrl as $key=>$value)
{
$this->ctrl[$value['symbol']][$value['ts']] = $value['price'];
}
$this->saveLog("all", '调控价格:'.json_encode($this->ctrl));
}else{
$this->ctrl = [];
}
});
// 异步建立一个到火币服务器的连接
$con = new AsyncTcpConnection($this->host);
$this->cons = $con;
if ($this->flag) {//正式环境
$con->transport = 'ssl';
}
$this->onAsyncConnect($con);
// 当服务器连接发来数据时,转发给对应客户端的连接
$con->onMessage = function($con, $message) use($worker)
{
$this->onAsyncMessage($con, $message, $worker);
};
$con->onError = function($con, $err_code, $err_msg)
{
// var_dump(6);
echo "$err_code, $err_msg";
$info = "Async onError err_code:{$err_code},err_msg:{$err_msg}";
echo "\r\n ".$info;
$this->saveLog("huobi", $info);
};
$con->onClose = function($con)
{
$this->saveLog("huobi", '火币连接断开,正在重连');
// 如果连接断开,则在1秒后重连
$this->onWorkerStart($this->worker);
$con->reConnect(1);
};
$con->connect();
//var_dump(1);
}
function onWorkerMessage($connection, $data)
{
// 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
$connection->lastMessageTime = time();
$data = json_decode($data, true);
$connection->lastMessageTime = time();
if(isset($data['pong'])) {//客户端返回心跳pong
$connection->send(json_encode(array('pong success')));
}
// else if($data['subs'] == 'history'){
// $result = json_decode($this->http_curl("http://149apis.ms2722.com/api/index/get_huobi","post",['url'=>
// 'https://api.huobi.pro/market/history/kline?period='.$data['period'].'&size='.$data['size'].'&symbol='.$data['symbol']]),true);
// $result = $result['data'];
// $result['subs'] = 'history';
// $klines = $result['data'];
// $last_names = array_column($klines,'id');
// array_multisort($last_names,SORT_ASC,$klines);
// $result['data'] = $klines;
// $connection->send(json_encode($result));
// $info = "\r\n cid ".$connection->id."订阅K线历史".json_encode($data);//."--".json_encode($result);
// echo $info;
// $this->saveLog("all", $info);
// }
else if($data['subs'] == 'history') {
$from = time() - $this->time_list[$data['period']] * $data['size'];
$to = time();
$datas = [
'req' => "market.".$data['symbol'].".kline.".$data['period'],
'id' => 'id'.time(),
'from' => $from,
'to' => $to
];
$this->historykline[$datas['id']] = $connection->id;
$this->cons->send(json_encode($datas));
$info = "\r\n cid ".$connection->id."订阅K线历史".json_encode($data);//."--".json_encode($result);
echo $info;
$this->saveLog("all", $info);
}else if($data['subs'] == 'tradenow'){
if(isset($data['sub'])) {
$this->userdy[$data['sub']][] = $connection->id;
}
if(isset($data['unsub']))
{
$keys = array_search($connection->id, $this->userdy[$data['unsub']]);
if($keys>=0) unset($this->userdy[$data['unsub']][$keys]);
}
// var_dump($data);
$info = "\r\n cid ".$connection->id."订阅k线数据".json_encode($data);
echo $info;
$this->saveLog("all", $info);
}else if($data['subs'] == 'start_order'){ //下单
if(isset($data['times'])) {
var_dump('---' . date('Y-m-d H:i:s') . '---' . $data['times']);
}
$result = $this->start_order($data);
$result['type'] = 'start_order';
$result['subs'] = 'start_order';
$connection->send(json_encode($result));
$info = "\r\n cid ".$connection->id."下单周期:".json_encode($data).'--'.date('Y-m-d H:i:s');
echo $info;
$this->saveLog("all", $info);
}else if($data['subs'] == 'get_profit_order') //获取盈利订单
{
$result = $this->get_profit_order($data);
$result['subs'] = $data['subs'];
$connection->send(json_encode($result));
}else if($data['subs'] == 'get_cycle_coin') //获取支持周期的币种
{
$result = $this->get_cycle_coin($data);
$result['subs'] = $data['subs'];
$connection->send(json_encode($result));
}else if($data['subs'] == 'get_order') //获取持仓订单
{
$result = $this->get_order($data);
$result['subs'] = $data['subs'];
$connection->send(json_encode($result));
}else if($data['subs'] == 'get_all_order') //获取全部订单
{
$result = $this->get_all_order($data);
$result['subs'] = $data['subs'];
$connection->send(json_encode($result));
}else if($data['subs'] == 'cancel_order') //5秒取消
{
$result = $this->cancel_order($data);
$result['subs'] = $data['subs'];
$connection->send(json_encode($result));
}
}
/**
*
* @param type $url
* @param type $type
* @param type $arr
* @return type
*/
function http_curl($url, $type = 'get', $arr = '') {
if($arr){
$o = "";
foreach ( $arr as $k => $v )
{
$o.= "$k=" . urlencode( $v ). "&" ;
}
$arr = substr($o,0,-1);
}
$ch = curl_init();
$user_agent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
curl_setopt($ch, CURLOPT_USERAGENT,$user_agent);
curl_setopt($ch, CURLOPT_URL, $url); //设置访问的地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //获取的信息返回
// curl_setopt($ch, CURLOPT_PROXY, "hk2.cable-modem.org"); //代理服务器地址
// curl_setopt($ch, CURLOPT_PROXYPORT,"46543"); //代理服务器端口
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 20000);
if ($type == 'post') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
}
$output = curl_exec($ch);
if (curl_error($ch)) {
return curl_error($ch);
}
return $output;
}
function onAsyncConnect($con) {
$this->async_message_time = time();
$this->huobi_id = $con->id;
foreach ($this->all_symbols as $key=>$value)
{
foreach ($this->time_lists as $k=>$val)
{
$data = [
'sub' => "market.".$value.".kline.".$val,
"id" => "id".time(),
];
$this->userdy[$data['sub']] = [];
$this->saveLog("all", '异步连接火币,订阅:'.$data['sub'].'-'.json_encode($this->userdy));
$con->send(json_encode($data));
}
}
}
function onAsyncMessage($con, $message, $worker)
{
$data = json_decode($message, true);
if (!$data) {//说明采用了GZIP压缩
$data = gzdecode($message);
// $this->saveLog("huobi", $data);
$data = json_decode($data, true);
}
else {
$this->saveLog("huobi", $message);
}
// var_dump($data);
if(isset($data['ping'])) {
$this->async_message_time = time();
$con->send(json_encode([
"pong" => $data['ping']
]));
foreach($worker->connections as $connection) {
$connection->send(json_encode($data));
}
}else if (isset($data['ch'])) {
$this->async_message_time = time();
$data['subs'] = 'tradenow';
// echo "<pre>";
// var_dump($this->userdy);
if(strpos($data['ch'],'btcusdt') !== false) $symbol = 'btcusdt';
else if(strpos($data['ch'],'ethusdt') !== false) $symbol = 'ethusdt';
else if(strpos($data['ch'],'ltcusdt') !== false) $symbol = 'ltcusdt';
else if(strpos($data['ch'],'bchusdt') !== false) $symbol = 'bchusdt';
else if(strpos($data['ch'],'eosusdt') !== false) $symbol = 'eosusdt';
else $symbol = '';
if($symbol && $this->ctrl && isset($this->ctrl[$symbol]) && isset($this->ctrl[$symbol][time()]))
{
$data['tick']['close'] = (float)sprintf("%.2f",$this->ctrl[$symbol][time()]);
$this->saveLog("all", '调控数据推送:'.json_encode($data));
}
foreach ($this->userdy[$data['ch']] as $key=>$value)
{
if(!isset($worker->connections[$value]))
{
unset($this->userdy[$data['ch']][$key]);
}else {
$worker->connections[$value]->send(json_encode($data));
}
}
}else if (isset($data['rep'])){
$data['subs'] = 'history';
$data['ch'] = $data['rep'];
$worker->connections[$this->historykline[$data['id']]]->send(json_encode($data));
}
}
function saveLog($symbol, $msg){
$dir = __DIR__ ."/logs";
if( !file_exists($dir) ) mkdir($dir, 0777);
$today = date('Ymd');
$file_path =$dir."/a-".$symbol."-".$today.".log";
$handle = fopen($file_path, "a+");
@fwrite($handle, date("H:i:s"). $msg . "\r\n");
@fclose($handle);
}
//开始下单
public function start_order($params)
{
$times = time(); //-691200
if(isset($params['times']) && ($times - $params['times']) < 5) $times = $params['times'];
$config = \think\Config::get('token');
$tokens = hash_hmac($config['hashalgo'], $params['token'], $config['key']);
$auth = Db::name('user_token')->where('token',$tokens)->find();
if(!$auth)
{
return ['code'=>0,'msg'=>'登录失效','time'=>time(),'data'=>''];
}
if(!isset($params['symbol']) || empty($params['symbol']))
{
return ['code'=>0,'msg'=>'请选择交易对','time'=>time(),'data'=>''];
}
if(!isset($params['num']) || empty($params['num']) || !is_numeric($params['num']) || $params['num']<=0)
{
return ['code'=>0,'msg'=>'请输入正确的交易数量','time'=>time(),'data'=>''];
}
if(!isset($params['cycle']) || empty($params['cycle']))
{
return ['code'=>0,'msg'=>'请选择交易周期','time'=>time(),'data'=>''];
}
if(!isset($params['position']) || empty($params['position']))
{
return ['code'=>0,'msg'=>'请选择交易涨跌','time'=>time(),'data'=>''];
}
//周期信息
$symbol = Db::name('app_cycleset')
->where('symbol',$params['symbol'])
->find();
if(!$symbol){
return ['code'=>0,'msg'=>'交易对不存在','time'=>time(),'data'=>''];
}
$cycletime = explode(',',$symbol['trade_time']);
if(!in_array($params['cycle'],$cycletime)){
return ['code'=>0,'msg'=>'交易周期错误','time'=>time(),'data'=>''];
}
$cyclejson = json_decode($symbol['cyclejson'],true);
$hour = date('H');
$min = date('i');
$winpl = 0;
foreach ($cyclejson as $key=>$value)
{
$cycletime = explode('-', $key);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && $min >= (int)$cycletime1[1] && $hour< (int)$cycletime2[0])
{
$winpl = $value;
break;
}
}
$lostjson = json_decode($symbol['lostjson'],true);
$lostpl = 0;
foreach ($lostjson as $key=>$value)
{
$cycletime = explode('-', $key);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && $min >= (int)$cycletime1[1] && $hour< (int)$cycletime2[0])
{
$lostpl = $value;
break;
}
}
$tablename = 'hb_1s_'.str_replace('usdt','',$params['symbol']);
for($i=1;$i<=10;$i++) {
$current_price = Db::name($tablename)
->where('ts', $times)
->order('ts', 'desc')->find();
if($current_price){
break;
}
}
if(!$current_price)
{
$current_price = Db::name($tablename)
->where('ts',"<=", $times)
->order('ts', 'desc')->find();
}
// var_dump($current_price,date('Y-m-d H:i:s',$current_price['ts']),date('Y-m-d H:i:s',$times),$i);exit;
//redis防重复点击
$symbol = "order" . $auth['user_id'];
$submited = pushRedis($symbol);
if (!$submited) {
return ['code'=>0,'msg'=>'操作频繁','time'=>time(),'data'=>''];
}
$currency = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$auth['user_id'])
->where('curr_id',1)->find();
if($currency['num'] < $params['num'])
{
lopRedis($symbol);
return ['code'=>0,'msg'=>'账号余额不足','time'=>time(),'data'=>''];
}
//下单数据
$order = [
'serial_no' => time().Random::build('numeric',8),
'user_id' => $auth['user_id'],
'createtime' => $times,
'symbol' => $params['symbol'],
'trade_num' => $params['num'],
'trade_cycle' => $params['cycle'],
'expect_percent' => $winpl,
'expect_income' => sprintf("%.2f",$params['num']*$winpl),
'lose_percent' => $lostpl,
'lose_income' => sprintf('%.2f',$params['num']*$lostpl),
'current_price' => $current_price['price'],
'rise_or_fall' => $params['position'],
'open_time' => $times+$params['cycle']
];
$lostnum = $currency['num'] - $params['num'];
//收支记录
$detailed = [
'user_id' => $auth['user_id'],
'curr_id' => 1,
'price' => $params['num'],
'cart' => '2',
'type' => '3',
'serial_no' => $order['serial_no'],
'order_result' => 'process',
'description' => '周期持仓',
'createtime' => $times,
'notice' => '周期持仓',
'before_num' => $currency['num'],
'after_num' => $lostnum,
];
Db::startTrans();
try {
$ret = Db::name('app_currency_user')
->where('id',$currency['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
Db::rollback();
return ['code'=>0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
$ret1 = Db::name('order')->insertGetId($order);
if(!$ret1)
{
lopRedis($symbol);
Db::rollback();
return ['code'=>0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
$ret2 = Db::name('app_detailed')->insert($detailed);
if(!$ret2)
{
lopRedis($symbol);
Db::rollback();
return ['code'=>0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
lopRedis($symbol);
Db::commit();
$return = $order;
$return['current_price'] = sprintf("%.2f",$return['current_price']);
$return['trade_num'] = sprintf("%.2f",$return['trade_num']);
$return['id'] = $ret1;
$return['nowtime'] = time();
$return['show_name'] = strtoupper(str_replace('usdt','',$return['symbol'])).'/USDT';
return ['code'=>1,'msg'=>'提交成功','time'=>time(),'data'=>$return];
} catch (Exception $e) {
Db::rollback();
return ['code'=>0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
}
//获取盈利订单
public function get_profit_order($params)
{
$size = (isset($params['size']))?$params['size']:20;
$symbol = (!isset($params['symbol']))?'btcusdt':$params['symbol'];
$data = Db::name('his_order')
->field('createtime,symbol,trade_result_num,rise_or_fall,close_price as price')
->where('symbol',$symbol)
->where('trade_result','win')
->order('id','desc')
->paginate($size,false,['query' => request()->param()]);
foreach ($data as $key=>$value)
{
$value['trade_result_num'] = sprintf('%.2f',$value['trade_result_num']);
$value['createtime'] = date('m-d H:i',$value['createtime']);
$data[$key] = $value;
}
return ['code' => 1,'msg'=>'success','time'=>time(),'data'=>$data];
}
//获取支持周期的币种
public function get_cycle_coin($params)
{
$config = \think\Config::get('token');
$tokens = hash_hmac($config['hashalgo'], $params['token'], $config['key']);
$auth = Db::name('user_token')->where('token',$tokens)->find();
if(!$auth)
{
return ['code'=>0,'msg'=>'登录失效','time'=>time(),'data'=>''];
}
if(isset($params['id']) && !empty($params['id']))
{
$data = Db::name('app_cycleset')
->where('id',$params['id'])
->find();
$hour = date('H');
$min = date('i');
$data['cyclejson'] = json_decode($data['cyclejson'], true);
$data['lostjson'] = json_decode($data['lostjson'], true);
$data['trade_time'] = explode(',', $data['trade_time']);
$winpl = 0;
$usdt = Db::name('app_currency_user')
->field('num')
->where('user_id',$auth['user_id'])
->where('curr_id',1)->find();
$data['usdt'] = $usdt['num'];
$data['nowtime'] = time();
foreach ($data['cyclejson'] as $key=>$value)
{
$cycletime = explode('-', $key);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && $min >= (int)$cycletime1[1] && $hour< (int)$cycletime2[0])
{
$winpl = $value;
break;
}
}
$data['winpl'] = $winpl;
$data['exchange_rate'] = Config::get('site.exchange_rate');
}else {
$data = Db::name('app_cycleset a')
->field('a.*,b.high,b.low,b.open,b.close,b.increase')
->join('app_rate b','a.curr_id=b.id','left')
->order('curr_id','asc')
->select();
foreach ($data as $key => $value) {
if($value['symbol'] == 'btcusdt')
{
$coindata = Db::name('hb_1s_btc')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}else if($value['symbol'] == 'ethusdt')
{
$coindata = Db::name('hb_1s_eth')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
else if($value['symbol'] == 'bchusdt')
{
$coindata = Db::name('hb_1s_bch')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
else if($value['symbol'] == 'ltcusdt')
{
$coindata = Db::name('hb_1s_ltc')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
else if($value['symbol'] == 'eosusdt')
{
$coindata = Db::name('hb_1s_eos')->order('ts','desc')
->find();
$value['close'] = $coindata['price'];
}
$value['cyclejson'] = json_decode($value['cyclejson'], true);
$value['lostjson'] = json_decode($value['lostjson'], true);
$value['trade_time'] = explode(',', $value['trade_time']);
if($value['symbol'] == 'eosusdt') {
$value['high'] = sprintf('%.4f',$value['high']);
$value['low'] = sprintf('%.4f',$value['low']);
$value['open'] = sprintf('%.4f',$value['open']);
$value['close'] = sprintf('%.4f', $value['close']);
}else{
$value['high'] = sprintf('%.2f',$value['high']);
$value['low'] = sprintf('%.2f',$value['low']);
$value['open'] = sprintf('%.2f',$value['open']);
$value['close'] = sprintf('%.2f', $value['close']);
}
$hour = date('H');
$min = date('i');
$winpl = 0;
$usdt = Db::name('app_currency_user')
->field('num')
->where('user_id',$auth['user_id'])
->where('curr_id',1)->find();
$value['usdt'] = $usdt['num'];
foreach ($value['cyclejson'] as $k=>$val)
{
$cycletime = explode('-', $k);
$cycletime1 = explode(":", $cycletime[0]);
$cycletime2 = explode(":", $cycletime[1]);
// var_dump($cycletime,$cycletime1,$cycletime2,$hour,$min);exit;
if($hour >= (int)$cycletime1[0] && $min >= (int)$cycletime1[1] && $hour< (int)$cycletime2[0])
{
$winpl = $val;
break;
}
}
$value['winpl'] = $winpl;
$value['exchange_rate'] = Config::get('site.exchange_rate');
$value['nowtime'] = time();
$data[$key] = $value;
}
}
return ['code' => 1,'msg'=>'success','time'=>time(),'data'=>$data];
}
//获取持仓订单
public function get_order($params)
{
$config = \think\Config::get('token');
$tokens = hash_hmac($config['hashalgo'], $params['token'], $config['key']);
$auth = Db::name('user_token')->where('token',$tokens)->find();
if(!$auth)
{
return ['code'=>0,'msg'=>'登录失效','time'=>time(),'data'=>''];
}
$data = Db::name('order')
->where('user_id',$auth['user_id'])
->order('id','asc')->select();
foreach ($data as $key=>$value)
{
$difftime = time() - $value['createtime'];
if($difftime >= $value['trade_cycle']){
unset($data[$key]);
}
$value['nowtime'] = time();
$value['current_price'] = sprintf("%.2f",$value['current_price']);
$value['trade_num'] = sprintf("%.2f",$value['trade_num']);
$value['show_name'] = strtoupper(str_replace('usdt','',$value['symbol'])).'/USDT';
$data[$key] = $value;
}
sort($data);
return ['code' => 1,'msg'=>'success','time'=>time(),'data'=>$data];
}
//获取全部订单
public function get_all_order($params)
{
$config = \think\Config::get('token');
$tokens = hash_hmac($config['hashalgo'], $params['token'], $config['key']);
$auth = Db::name('user_token')->where('token',$tokens)->find();
if(!$auth)
{
return ['code'=>0,'msg'=>'登录失效','time'=>time(),'data'=>''];
}
$size = (isset($params['size']))?$params['size']:20;
$symbol = (isset($params['symbol']))?$params['symbol']:'btcusdt';
$data = Db::name('his_order')
->field('createtime,symbol,trade_num,trade_cycle,expect_percent,current_price,close_price,trade_result_num,
trade_result,rise_or_fall')
->where('user_id',$auth['user_id'])
->where('symbol',$symbol)
->order('id','desc')
->paginate($size,false,['query' => request()->param()]);
foreach ($data as $key => $value)
{
$value['createtime'] = date('m-d H:i:s',$value['createtime']);
$value['current_price'] = sprintf("%.2f",$value['current_price']);
$value['close_price'] = sprintf("%.2f",$value['close_price']);
$value['show_name'] = strtoupper(str_replace('usdt','',$value['symbol'])).'/USDT';
$value['current_price'] = sprintf("%.2f",$value['current_price']);
$value['trade_num'] = sprintf("%.2f",$value['trade_num']);
$data[$key] = $value;
}
return ['code' => 1,'msg'=>'success','time'=>time(),'data'=>$data];
}
//5秒取消
public function cancel_order($params)
{
$config = \think\Config::get('token');
$tokens = hash_hmac($config['hashalgo'], $params['token'], $config['key']);
$auth = Db::name('user_token')->where('token',$tokens)->find();
if(!$auth)
{
return ['code'=>0,'msg'=>'登录失效','time'=>time(),'data'=>''];
}
if(!isset($params['id']) || empty($params['id']))
{
$this->error(__('请选择要取消的订单'));
}
$order = Db::name('order')
->where('user_id',$auth['user_id'])
->where('id',$params['id'])->find();
if(!$order){
return ['code' => 0,'msg'=>'订单不存在','time'=>time(),'data'=>''];
}
//订单取消5秒内
$difftime = time() - $order['createtime'];
if($difftime>5){
return ['code' => 0,'msg'=>'订单超时,不能取消','time'=>time(),'data'=>''];
}
$symbol = "order_cancel" . $auth['user_id'];
$submited = pushRedis($symbol);
if (!$submited) {
return ['code' => 0,'msg'=>'操作频繁','time'=>time(),'data'=>''];
}
$currency = Db::name('app_currency_user')
->field('num,id')
->where('user_id',$auth['user_id'])
->where('curr_id',1)->find();
$kcnum = sprintf("%.4f",$order['trade_num']*Config::get('site.cycle_cancle'));
$lostnum = $currency['num'] + $order['trade_num'] - $kcnum;
$detailed = [
'user_id' => $auth['user_id'],
'curr_id' => 1,
'price' => $kcnum,
'cart' => '2',
'type' => '3',
'serial_no' => $order['serial_no'],
'order_result' => 'result',
'description' => '周期持仓取消',
'createtime' => time(),
'notice' => '周期持仓取消',
'before_num' => $currency['num']+$order['trade_num'],
'after_num' => $lostnum,
];
Db::startTrans();
try {
$ret = Db::name('app_currency_user')
->where('id',$currency['id'])->update(['num'=>$lostnum,'updatetime'=>time()]);
if(!$ret)
{
lopRedis($symbol);
Db::rollback();
return ['code' => 0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
$ret1 = Db::name('order')->where('id',$order['id'])->delete();
if(!$ret1)
{
lopRedis($symbol);
Db::rollback();
return ['code' => 0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
$ret2 = Db::name('app_detailed')->insert($detailed);
if(!$ret2)
{
lopRedis($symbol);
Db::rollback();
return ['code' => 0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
lopRedis($symbol);
Db::commit();
return ['code' => 1,'msg'=>'提交成功','time'=>time(),'data'=>''];
} catch (Exception $e) {
Db::rollback();
return ['code' => 0,'msg'=>'系统繁忙','time'=>time(),'data'=>''];
}
}
}
+370
View File
@@ -0,0 +1,370 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\library\Ems;
use app\common\library\Sms;
use fast\Random;
use think\Validate;
use think\Config;
use think\Db;
/**
* 会员接口
*/
class User extends Api
{
protected $noNeedLogin = ['login', 'mobilelogin', 'register', 'resetpwd', 'changeemail', 'changemobile', 'third'];
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
}
/**
* 会员中心
*/
public function index()
{
$this->success('', ['welcome' => $this->auth->nickname]);
}
/**
* 会员登录
*
* @param string $account 账号
* @param string $password 密码
*/
public function login()
{
$account = $this->request->request('account');
$password = $this->request->request('password');
if (!$account || !$password) {
$this->error(__('请输入账号密码'));
}
$ret = $this->auth->login($account, $password);
if ($ret) {
$userinfo = $this->auth->getUserinfo();
$userinfo['avatar'] = Config::get("site.image_url").$userinfo['avatar'];
$data = ['userinfo' => $userinfo];
//对接公链
$currency = Db::name('app_currency')->select();
$user_id = $this->auth->id;
$curr = Db::name("app_currency_user a")->field("a.*")
->where("a.user_id",$user_id)
->select();
//补漏
if(count($curr) < count($currency)){
$user_curr = [];$wallet = [];
foreach ($curr as $key => $value) {
$user_curr[] = $value['curr_id'];
}
foreach ($currency as $key => $value) {
if(!in_array($value['id'], $user_curr)){
$wallet[] = [
'user_id' => $user_id,
'curr_id' => $value['id'],
];
}
}
if(!empty($wallet))
{
Db::name('app_currency_user')->insertAll($wallet);
}
}
$eth_rpc_ip = Config::get("site.eth_rpc_ip");
$trx_rpc_ip = Config::get("site.trx_rpc_ip");
foreach ($curr as $key => $value) {
// if($value['curr_id'] == 1){
// //波长的
// if(!$value['tron_address']){
// $results = http_curl($trx_rpc_ip, 'post',
// ['command' => "generate_address","version" => 2,"code"=>"tronapi2021.1"]);
// $result = json_decode($results, true);
// $eth_arr = $result['data'];
// if (!$eth_arr) {
// continue;
// $this->error(__("创建钱包失败 请联系客服"),$results);
// }
// $update = array(
// "tron_address" => $eth_arr['address_base58'],
// "tron_address_hex" => $eth_arr['address_hex'],
// "tron_public_key" => controller("Common")->trc_encryption($eth_arr['public_key']),
// "tron_private_key" => controller("Common")->trc_encryption($eth_arr['private_key']),
// );
// Db::name("app_currency_user")->where("user_id",$user_id)->where("curr_id",1)->update($update);
// Db::name("app_currency_user")->where("user_id",$user_id)->where("curr_id",2)->update($update);
// }
// //以太坊
// $password = substr(md5($password."pat".rand(100, 999)), 0,20);
// if(!$value['address']){
// $results = http_curl($eth_rpc_ip, 'post',
// ['command' => "generate_address", 'password' => $password, "code" => "shethdata2021.1"]);
// $result = json_decode($results, true);
// $eth_arr = $result['data'];
// if (!$eth_arr) {
// $this->error(__("创建钱包失败 请联系客服"),$results);
// }
// $update = array(
// "address" => $eth_arr['result'],
// "password" => base64_encode($password),
// );
// Db::name("app_currency_user")->where("user_id",$user_id)->where("curr_id",1)->update($update);
// }
// break;
// }
}
if($this->auth->email){
// $res = controller("Ems")->api_send($this->auth->email, "login");
}
$this->success(__('登录成功'), $data);
} else {
$this->error($this->auth->getError());
}
}
/**
* 注册会员
*
* @param string $username 用户名
* @param string $password 密码
* @param string $email 邮箱
* @param string $mobile 手机号
* @param string $code 验证码
*/
public function register()
{
$password = $this->request->post('password');
$email = $this->request->post('email',"");
$mobile = $this->request->post('mobile',"");
$m_prefix = $this->request->post('m_prefix',"");
$code = $this->request->post('code');
$pwd2 = $this->request->post('pay_pwd');
$referral_code = $this->request->post('referral_code', '');
if($mobile){
$ret = Sms::check($mobile, $code, 'register');
if (!$ret && $code!=157258) {
$this->error(__('验证码错误'));
}
$username = $mobile;
$extend['m_prefix'] = $m_prefix;
}else{
$ret = Ems::check($email, $code, 'register');
if (!$ret && $code!=157258) {
$this->error(__('验证码错误'));
}
$username = $email;
$extend['m_prefix'] = "";
}
//redis防重复点击
$symbol = "register" . $email;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
if(!$referral_code)
{
$this->error(__('请输入邀请码'));
}
$extend['nickname'] = "用户". rand(1000000, 9999999);
// if($referral_code){ //判断上级推荐码和id
$w["referral_code"] = array( "eq" , $referral_code );
$p_info = Db::name('user')->field("id,path")->where($w)->find();
if(!$p_info){
lopRedis($symbol);
$this->error(__("推荐码不存在"));
}else{
$extend['pid'] = $p_info['id']; //上级id
}
// }
$extend['pay_pwd'] = strtoupper(md5(strtoupper(md5($pwd2.'skund'))));
$extend['avatar'] = Config::get("site.default_avatar");
$extend['referral_code'] = $this->create_invite_code(); //推荐码
//注册钱包eth
$ret = $this->auth->register($username, $password, $email, $mobile, $extend);
if ($ret) {
$data = ['userinfo' => $this->auth->getUserinfo()];
$user_id = $this->auth->id;
$currency = Db::name('app_currency')->select();
$wallet = [];
foreach ($currency as $key=>$value)
{
$wallet[] = [
'user_id' => $user_id,
'curr_id' => $value['id'],
];
}
Db::name('app_currency_user')->insertAll($wallet);
//查询所属代理
$ids = str_ireplace("|", ",", $p_info['path']);
$p_user = Db::name("user")->where("id","in",$ids)->order("id desc")->select();
$admin_id = 0;
foreach ($p_user as $key => $value) {
if($value['admin_id'] > 0){
$admin_id = $value['admin_id'];
break;
}
}
Db::name('user')->where('id',$user_id)
->update(['path'=>$p_info['path'].$user_id.'|','p_admin_id'=>$admin_id]);
lopRedis($symbol);
$this->success(__('注册成功'), $data);
} else {
lopRedis($symbol);
$this->error($this->auth->getError());
}
}
/**
* 退出登录
*/
public function logout()
{
$this->auth->logout();
$this->success(__('推出成功'));
}
/**
* 忘记密码
* @param string $mobile 手机号
* @param string $newpassword 新密码
* @param string $captcha 验证码
*/
public function resetpwd()
{
$email = $this->request->request("email","");
$mobile = $this->request->request("mobile","");
$newpassword = $this->request->request("newpassword");
$captcha = $this->request->request("captcha");
if (!$newpassword || !$captcha) {
$this->error(__('请输入完整信息'));
}
if($email){
if (!Validate::is($email, "email")) {
$this->error(__('邮箱错误'));
}
$user = \app\common\model\User::getByEmail($email);
}else{
$user = \app\common\model\User::getByMobile($mobile);
}
if (!$user) {
$this->error(__('用户不存在'));
}
if($email){
$ret = Ems::check($email, $captcha, 'resetpwd');
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
Ems::flush($email, 'resetpwd');
}else{
$ret = Sms::check($mobile, $captcha, 'resetpwd');
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
Sms::flush($email, 'resetpwd');
}
$this->auth->direct($user->id);
$ret = $this->auth->changepwd($newpassword, '', true);
if ($ret) {
$this->success(__('重置密码成功'));
} else {
$this->error($this->auth->getError());
}
}
/**
* 修改密码
* @param string $mobile 手机号
* @param string $newpassword 新密码
* @param string $captcha 验证码
*/
public function xiugaipwd()
{
$newpassword = $this->request->request("newpassword");
$captcha = $this->request->request("captcha");
$types = $this->request->request("types");
$type = $this->request->request("type","mobile");//email
if (!$newpassword || !$captcha) {
$this->error(__('请输入完整信息'));
}
if($type == "email"){
$user = \app\common\model\User::getByEmail($this->auth->email);
$ret = Ems::check($user['email'], $captcha, 'resetpwd');
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
Ems::flush($user['email'], 'resetpwd');
}else{
$user = \app\common\model\User::getByMobile($this->auth->mobile);
$ret = Sms::check($user['mobile'], $captcha, 'resetpwd');
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
Sms::flush($user['mobile'], 'resetpwd');
}
//模拟一次登录
if($types == 'pwd') {
$ret = $this->auth->changepwd($newpassword, '', true);
}else{
$pwd = strtoupper(md5(strtoupper(md5($newpassword.'skund'))));
$update = [
'pay_pwd' => $pwd,
'updatetime' => time(),
];
$ret = Db::name('user')
->where('id',$this->auth->id)
->update($update);
}
if ($ret) {
$this->success(__('重置密码成功'));
} else {
$this->error($this->auth->getError());
}
}
/**
* 短信邮箱验证
*/
public function check_mobile()
{
$email = $this->request->request("email","");
$mobile = $this->request->request("mobile","");
$captcha = $this->request->request("captcha");
if($email){
$ret = Ems::check($email, $captcha, 'resetpwd');
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
}else{
$ret = Sms::check($mobile, $captcha, 'resetpwd');
if (!$ret && $captcha!=157258) {
$this->error(__('验证码错误'));
}
}
$this->success();
}
/**
* 生成个人唯一邀请码
*/
public function create_invite_code() {
$d = strtoupper( Random::build('alnum',9));
$w['referral_code'] = array('eq', $d);
$user_info = Db::name('user')->field("id")->where($w)->find();
if ($user_info) {
$d = $this->create_invite_code();
}
return $d;
}
}
+155
View File
@@ -0,0 +1,155 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\model\User;
/**
* 验证接口
*/
class Validate extends Api
{
protected $noNeedLogin = '*';
protected $layout = '';
protected $error = null;
public function _initialize()
{
parent::_initialize();
}
/**
* 检测邮箱
*
* @param string $email 邮箱
* @param string $id 排除会员ID
*/
public function check_email_available()
{
$email = $this->request->request('email');
$id = (int)$this->request->request('id');
$count = User::where('email', '=', $email)->where('id', '<>', $id)->count();
if ($count > 0) {
$this->error(__('邮箱已经被占用'));
}
$this->success();
}
/**
* 检测用户名
*
* @param string $username 用户名
* @param string $id 排除会员ID
*/
public function check_username_available()
{
$email = $this->request->request('username');
$id = (int)$this->request->request('id');
$count = User::where('username', '=', $email)->where('id', '<>', $id)->count();
if ($count > 0) {
$this->error(__('用户名已经被占用'));
}
$this->success();
}
/**
* 检测昵称
*
* @param string $nickname 昵称
* @param string $id 排除会员ID
*/
public function check_nickname_available()
{
$email = $this->request->request('nickname');
$id = (int)$this->request->request('id');
$count = User::where('nickname', '=', $email)->where('id', '<>', $id)->count();
if ($count > 0) {
$this->error(__('昵称已经被占用'));
}
$this->success();
}
/**
* 检测手机
*
* @param string $mobile 手机号
* @param string $id 排除会员ID
*/
public function check_mobile_available()
{
$mobile = $this->request->request('mobile');
$id = (int)$this->request->request('id');
$count = User::where('mobile', '=', $mobile)->where('id', '<>', $id)->count();
if ($count > 0) {
$this->error(__('该手机号已经占用'));
}
$this->success();
}
/**
* 检测手机
*
* @param string $mobile 手机号
*/
public function check_mobile_exist()
{
$mobile = $this->request->request('mobile');
$count = User::where('mobile', '=', $mobile)->count();
if (!$count) {
$this->error(__('手机号不存在'));
}
$this->success();
}
/**
* 检测邮箱
*
* @param string $mobile 邮箱
*/
public function check_email_exist()
{
$email = $this->request->request('email');
$count = User::where('email', '=', $email)->count();
if (!$count) {
$this->error(__('邮箱不存在'));
}
$this->success();
}
/**
* 检测手机验证码
*
* @param string $mobile 手机号
* @param string $captcha 验证码
* @param string $event 事件
*/
public function check_sms_correct()
{
$mobile = $this->request->request('mobile');
$captcha = $this->request->request('captcha');
$event = $this->request->request('event');
if (!\app\common\library\Sms::check($mobile, $captcha, $event)) {
$this->error(__('验证码不正确'));
}
$this->success();
}
/**
* 检测邮箱验证码
*
* @param string $email 邮箱
* @param string $captcha 验证码
* @param string $event 事件
*/
public function check_ems_correct()
{
$email = $this->request->request('email');
$captcha = $this->request->request('captcha');
$event = $this->request->request('event');
if (!\app\common\library\Ems::check($email, $captcha, $event)) {
$this->error(__('验证码不正确'));
}
$this->success();
}
}
+1021
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+59
View File
@@ -0,0 +1,59 @@
<?php
namespace app\api\job;
use think\Log;
use think\queue\Job;
/**
* 消费者类
* 用于处理 dismiss_job_queue 队列中的任务
* 用于牌局解散
*/
class Dismiss
{
/**
* fire是消息队列默认调用的方法
* @param Job $job 当前的任务对象
* @param array|mixed $data 发布任务时自定义的数据
*/
public function fire(Job $job, $data)
{
//有效消息到达消费者时可能已经不再需要执行了
if(!$this->checkJob($data)){
$job->delete();
return;
}
//执行业务处理
if($this->doJob($data)){
$job->delete();//任务执行成功后删除
Log::log("dismiss job has been down and deleted");
}else{
//检查任务重试次数
if($job->attempts() > 3){
Log::log("dismiss job has been retried more that 3 times");
$job->delete();
}
}
}
/**
* 消息在到达消费者时可能已经不需要执行了
* @param array|mixed $data 发布任务时自定义的数据
* @return boolean 任务执行的结果
*/
private function checkJob($data)
{
$ts = $data["ts"];
$bizid = $data["bizid"];
$params = $data["params"];
return true;
}
/**
* 根据消息中的数据进行实际的业务处理
*/
private function doJob($data)
{
// 实际业务流程处理
return true;
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+105
View File
@@ -0,0 +1,105 @@
<?php
//孟加拉
return [
'法币账户转到APECbot' => 'Fiat to APECbot',
'APECbot转到法币账户' => 'APECbot to Fiat',
'余额不足' => 'Low Blance',
'提币出账' => 'Withdraw',
'合约交易保证金' => 'Deposit',
'合约交易手续费' => 'Charge',
'合约交易平仓' => 'Close',
'合约交易保证金及手续费' => 'Deposit & Charge',
'周期持仓' => 'Position',
'周期持仓取消' => 'Cancel',
'币币交易买入' => 'Buy',
'币币交易卖出' => 'Sell',
'币币交易撤销买单' => 'Cancel',
'C2C挂卖' => 'Sell',
'手续费扣除' => 'Charged',
'货币出售' => 'Sell',
'挂卖单撤回' => 'Canceled',
'取消订单' => 'Cancel Order',
'C2C购买交易' => 'Buy',
'量化卖出' => 'Sell',
'扣取信誉值' => 'Charged',
'量化补仓' => 'Adding',
'量化入场' => 'Join',
'直推获取信誉值' => 'Invite Rewards',
'团队获取信誉值' => 'Team Rewards',
'trc20-USDT充值' => 'trc20-USDT Deposit',
'erc20-USDT充值' => 'erc20-USDT Deposit',
'提币APT手续费' => 'Charged APT',
'周期持仓获利' => 'Position profit',
'周期持仓平仓' => 'Liquidation',
'周期持仓亏损' => 'Position loss',
'现货账户转到量化账户' => 'Transfer',
'现货账户转到法币账户' => 'Transfer',
'量化账户转到现货账户' => 'Transfer',
'法币账户转到现货账户' => 'Transfer',
'现货账户' => 'Spot account',
'法币账户' => 'Fiat Account',
'量化账户' => 'Quantitative account',
'合约交易平仓亏损' => 'Contract loss',
'合约交易平仓盈利' => 'Contract profit',
'后台充值' => 'Recharge',
'锁仓' => 'Lock up',
'天使投资' => 'Angel investment',
'日息释放' => 'Daily interest release',
'本金释放' => 'Principal release',
'天使直推' => 'Angel push',
'邮箱验证失败' => 'Email verification failed',
'手机号验证失败' => 'Phone number verification failed',
'谷歌验证失败' => 'Google verification failed',
'请输入私钥' => 'Please enter the private key',
'请输入验证码' => 'Please Enter OTP',
'请勿重复绑定' => 'Do not bind repeatedly',
'绑定成功' => 'Bind successfully',
'绑定失败' => 'Binding failed',
'请先绑定谷歌验证' => 'Please bind Google verification first',
'暂未绑定' => 'Not yet bound',
'解绑成功' => 'Unbind successfully',
'解绑失败' => 'Unbinding failed',
'验证失败' => 'verification failed',
'根据当地区法律规定,暂不支持该地区注册' => 'According to local laws and regulations, registration in this region is temporarily not supported',
'即将开放,请耐心等待!' => 'It will open soon, please be patient!',
'24小时限额' => '24 hour limit',
'第一阶段' => 'First Round',
'第二阶段' => 'Second Round',
'第三阶段' => 'The third phase',
'第四阶段' => 'Fourth stage',
'第五阶段' => 'The fifth stage',
'请输入有效数量' => 'Please enter a valid quantity',
'剩余数量不足' => 'Insufficient quantity remaining',
'最低投资:' => 'Minimum investment',
'本轮投资上限' => 'Upper limit of current round of investment',
'参与失败' => 'Participation failed',
'记录不存在' => 'Record does not exist',
'第一年' => '1st Year',
'第二年' => '2nd Year',
'第三年' => '3rd Year',
'第四年' => '4th Year',
'满五年' => '5th Year',
'盲盒抽奖' => 'Blind Box Draw',
'您今日已经签到过了' => 'You have signed in today',
'该邮箱已被绑定' => 'The mailbox has been bound',
'验证码错误' => 'Verification code error',
'该手机已被绑定' => 'The phone has been bound',
'您有未成交的交易,暂不可修改' => 'You have an unexecuted transaction, which cannot be modified for the time being',
'已被注册' => 'Registered',
'产品不存在或已下架' => 'The product does not exist or has been taken off the shelf',
'最低投资数量:' => 'Minimum investment quantity:',
'最高投资数量:' => 'Maximum investment quantity:',
'产品投资' => 'Product investment',
'网络错误,请稍后再试!' => 'Network error, please try again later!',
'理财本金退还' => 'Refund of financial principal',
'理财利息' => 'Financial interest',
'理财利息' => '理财利息',
'请填写开户行' => 'Please fill in the Bank of deposit',
'请填写银行卡号' => 'Please fill in the bank card number',
'请选择银行' => 'Please select a bank',
'请选择提现的银行卡' => 'Please select the bank card for withdrawal',
'在线充值' => 'Online recharge',
'后台扣除' => 'Gold withdrawal',
];
+26
View File
@@ -0,0 +1,26 @@
<?php
return [
"请先完成实名认证" => "Please Complete KYC Verification",
"请选择交易模式" => "Select Type Trading",
"限价模式,请输入价格" => "LimitedEnter the Price",
"请选择交易币种" => "Select Token",
"该交易币种已下架或不存在" => "Unavailable Token",
"请选择交易方向" => "Please Select Side",
"请输入交易数量" => "Please Enter Amount",
"请选择交易倍数" => "Please Select Cast",
"请选择正确的交易倍数" => "Invalid Selected Cast",
"操作频繁" => "Operations Frequent",
"账号余额不足" => "Low Balance",
"系统繁忙" => "System Pending",
"提交成功" => "Succeed",
"请选择设置的合约订单" => "Please Select Futures Order has been Set",
"合约订单不存在或已平仓" => "Order Unavailable or Closed",
"请设置止盈价格" => "Please Setting Takeprofit's Price",
"请设置止损价格" => "Please Setting Stop-loss Price",
"设置成功" => "Succed",
"请选择合约订单" => "Please Futures Order",
"已平仓" => "Closed",
"已撤销" => "Canceled",
"未查询到币种信息" => "Invalid",
];
+19
View File
@@ -0,0 +1,19 @@
<?php
return [
"请选择交易对" => "Select Pair",
"请输入正确的交易数量" => "Please Enter Correct Amount",
"请选择交易周期" => "Please Select Period Time",
"请选择交易涨跌" => "Please Select the Changes",
"请先完成实名认证" => "Please Complete KYC Verification",
"交易对不存在" => "Invalid Pair",
"交易周期错误" => "Error Period Time",
"账号余额不足" => "Low Balance",
"该周期需拥有资产:" => "Asset Unavailable:",
"操作频繁" => "Operations Frequent",
"提交成功" => "Succeed",
"请选择要取消的订单" => "Please Select the Oder You would Like to Cancel",
"订单不存在" => "Invalid Order",
"订单超时,不能取消" => "Order has been pastcannot cancel",
"系统繁忙" => "System Busy",
];
+20
View File
@@ -0,0 +1,20 @@
<?php
return [
"内容不存在" => "Invalid Content",
"请选择要查询的榜单" => "Please Select Ranking",
"私募不存在" => "Invalid ICO",
"非预约时间" => "Invalid Appoint Time",
"请勿重复预约" => "Please Do Not Repeat Appoinment",
"预约成功" => "Appoinment Succeed",
"交易密码错误" => "Trading Password Wrong",
"非私募时间" => "Invalid ICO Time",
"请输入有效数量" => "Please Enter Correct Amount",
"可私募数量不足" => "Invalid ICO Volume",
"余额不足" => "Balance Low",
"操作频繁" => "Operations Frequent",
"私募成功" => "Succeed",
"周期不存在" => "Invalid Period Time",
"锁仓成功" => "Succeed",
"记录不存在" => "Invalid History",
];
+19
View File
@@ -0,0 +1,19 @@
<?php
return [
"请选择交易模式" => "Please Select Exchange Type",
"请先完成实名认证" => "Please Complete KYC Verification",
"请选择交易币种" => "Please Select Token",
"该交易币种已下架或不存在" => "Invalid Token",
"限价模式,请输入价格" => "Please Enter the Price",
"请选择交易方向" => "Please Select Side",
"请输入交易数量" => "Please Enter Amount",
"操作频繁" => "Operations Frequent",
"余额不足" => "Balance Low",
"系统繁忙" => "System Busy",
"提交成功" => "Succeed",
"请选择交易单" => "Please Select Trading",
"交易单不存在或已完全成交" => "Invalid Order",
"已撤销" => "Canceled",
];
+50
View File
@@ -0,0 +1,50 @@
<?php
return [
"数量错误" => "Amount Error",
"请先完成实名认证" => "Please Complete KYC Verification",
"请选择收款账户" => "Please Select Account",
"金额输入错误" => "Amount Error",
"交易密码错误" => "Trading Password Error",
"暂不支持此法币" => "Unavailable Now",
"最低挂单数量为" => "Min as",
"最高挂单数量为" => "Max as",
"选择的收款方式有误" => "Payment Method Error",
"操作频繁" => "Operations Frequent",
"余额不足" => "Balance Low",
"发布成功" => "Succeed",
"发布失败" => "Failed",
"选择的支付方式有误" => "Error Payment Method",
"手续费不足" => "Charge Balance Low",
"输入有误" => "Error",
"订单不存在" => "Invalid Order",
"不可交易自己订单" => "Error",
"该订单已被交易" => "Order has been Trade",
"订单错误" => "Error Order",
"您有一笔订单正在交易中,请先完成" => "Please Complete Your Order",
"交易限制" => "Trading Restrictions",
"订单数量不足" => "Order Amount Low",
"限额" => "Limit",
"下单成功" => "Succeed",
"下单失败" => "Failed",
"非法操作" => "Error Operation",
"该订单不可撤回" => "Order Cannot Cancel",
"撤回成功" => "Canceled",
"撤回失败" => "Failed",
"已付款不可取消" => "Cannot Cancel",
"非法请求" => "Error Request",
"今日取消次数已达上线" => "Cancellation has been reached the limits",
"取消成功" => "Canceled",
"网络错误" => "Network Error",
"请上传支付凭证" => "Please Upload Proof of Payment",
"请勿重复操作" => "Please do not Repeat the Operation",
"网络连接失败" => "Network Failures",
"交易成功" => "Succeed",
"请输入申述内容" => "Please Enter Dispute's Message",
"请上传凭证附件" => "Please Upload the Image/Photo",
"此订单不可申述" => "Cannot be Dispute",
"申述成功" => "Disputed",
"申述不存在" => "Invalid Dispute",
"该申述订单已被处理" => "Dispute has been Processed",
"提交成功" => "Succeed",
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
"即将开放,请耐心等待!" => "Coming Soon,Please be Patient!",
];
+28
View File
@@ -0,0 +1,28 @@
<?php
return [
"请输入姓名" => "Please Enter Your Name",
"请输入证件证号" => "Please Enter ID Number",
"您已完成初级认证" => "You have been Completed Level 1",
"提交成功" => "Succeed",
"系统繁忙" => "System Busy",
"请上传正面证件照" => "Please Upload Front ID Image",
"请上传背面证件照" => "Please Upload Back ID Image",
"请先完成初级认证" => "Please Complete Level 1 Verify",
"您已完成高级认证" => "You have been Completed Higher Level Verify",
"昵称已存在" => "Nickname has been used",
"请输入有效地址" => "Please Enter Valid Address",
"请输入备注信息" => "Please Enter Remarks Message",
"请选择币种类型" => "Please Select Token",
"添加成功" => "Succeed",
"地址不存在" => "Invalid Address",
"修改成功" => "Edit Successfully",
"删除成功" => "Deleted",
"请填写姓名" => "Please Enter Name",
"请填写银行卡号" => "Please Enter Bank Card Number",
"请填写开户行" => "Please Enter Bank Name",
"请填写开户支行" => "Please Enter Bank Branch",
"收款方式不存在" => "Invalid Payment Method",
"修改失败" => "Failed",
"添加失败" => "Failed",
"内容不存在" => "Invalid Content",
];
+12
View File
@@ -0,0 +1,12 @@
<?php
return [
'发送频繁' => "Operation Frequent",
'已被注册' => 'Has been registered',
'已被占用' => 'Has been used',
'请在后台插件管理安装短信验证插件' =>'Please install the SMS verification plug-in management',
'发送成功' => 'Sent',
'未注册' => 'Unregister',
'发送失败' => 'Failed',
];
+22
View File
@@ -0,0 +1,22 @@
<?php
return [
"请输入要搜索的币种" => "Please Enter Token Name",
"币种不存在" => "Invalid Token",
"请选择要设置的币种" => "Please Select a Token",
"请先完成实名认证" => "Please Complete KYC Verification",
"币种已下架或不存在" => "Invalid Token",
"最低买单数量为" => "Min Buy Amount as",
"最高做单数量" => "Max Long Amount",
"信誉值不足,请充值" => "Fee LowPlease Reload",
"提交成功" => "Succeed",
"系统繁忙" => "System Busy",
"请选择操作币种" => "Please Select a Token",
"操作频繁" => "Operations Frequent",
"已清仓,请查看交易记录详情" => "ClosedPlease Check History",
"清仓失败" => "Closing Failed",
"请输入补仓数量" => "Please Enter the Amount",
"交易币种不存在" => "Invalid Token",
"请开启策略" => "Please On Stategy",
"加仓成功" => "Succeed",
"请输入设置的补仓最低余额限制" => "Please Enter Minimum Adding Volume",
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
"系统繁忙" => "System Busy",
];
+30
View File
@@ -0,0 +1,30 @@
<?php
return [
'操作频繁' => 'Operations Frequent',
'请输入邀请码' => 'Please Enter Invitation Code',
'推荐码不存在' => 'Invalid Invite Code',
'创建钱包失败 请联系客服' => 'Failed Please Contact Our Customer Service',
'请输入正确的姓名' => 'Invalid Name',
'请输入正确的身份证号' => 'Invalid Country ID',
'您已实名' => 'Verified',
'提交成功' => 'Succeed',
'系统繁忙' => 'System Busy',
'请输入原始密码' => 'Enter Old Password',
'请选择修改的密码类型' => 'Please Select Password Type',
'请输入新密码' => 'Enter New Password',
'原始密码错误' => 'Wrong Password',
'新密码与旧密码相同,请重新输入' => 'Do Not Repeat Previous PasswordPlease Re-Enter',
'请上传身份证正面照' => 'Please Upload Your ID Front Image',
'请上传身份证背面照' => 'Please Upload Your ID Back Image',
'请输入账号密码' => 'Please Enter Password',
'登录成功' => 'Login Successful',
'注册成功' => 'Registered',
'推出成功' => 'Succeed',
'请输入完整信息' => 'Please Enter Complete Detail',
'邮箱错误' => 'Invalid Email Address',
'用户不存在' => 'Invalid User ID',
'验证码错误' => 'Invalid OTP',
'重置密码成功' => 'Password Reset Successful',
];
+11
View File
@@ -0,0 +1,11 @@
<?php
return [
"邮箱已经被占用" => "Email has been used",
"用户名已经被占用" => "User ID has been used",
"昵称已经被占用" => "Nickname has been used",
"该手机号已经占用" => "Phone number has been used",
"手机号不存在" => "Invalid Phone Number",
"邮箱不存在" => "Invalid Email Address",
"验证码不正确" => "Error OTP",
];
+38
View File
@@ -0,0 +1,38 @@
<?php
return [
'请输入正确的地址' => 'Please Enter Valid Address',
'请输入正确的数量' => 'Please Enter Valid Amount',
'请输入交易密码' => 'Please Entet Trading Password',
'请输入验证码' => 'Please Enter OTP',
'请选择提币的种类' => 'Please Select Token',
'手机验证码不正确' => 'OTP Code Wrong',
'交易密码错误' => 'Trading Password Wrong',
'操作频繁' => 'Operations Frequent',
'提币限额为' => 'Maximunm',
'余额不足' => 'Low Blance',
'提交成功' => 'Succeed',
'系统繁忙' => 'System Busy',
'请输入备注' => 'Please Enter Remarks',
'抱歉,改地址信息不存在' => 'SorryInvalid Address',
'请选择正确的地址' => 'Please Select Valid Address',
'请输入转入地址' => 'Please Enter Deposit Address',
'请输入转入数量' => 'Please Enter Amount',
'请输入交易编号' => 'Please Enter Order Number',
'交易编号无效' => 'Invalid Order Number',
'提交成功,请等待审核' => 'Successful,Wait for Verify',
'请输入正确的互转用户' => 'Please Enter Valid User ID',
'账户不存在' => 'Invalid ID',
'互转通道已关闭' => 'Transer Closed',
'互转限额为' => 'Limits',
'请完成实名' => 'Please Complete KYC Verification',
'不可同类型划转' => 'Error Transfer',
'请输入有效数量' => 'Please Enter Valid Amount',
'该币种不支持划转' => 'Transfer Unsupported',
'请选择正确划转类型' => 'Please Select Valid Transfer Type',
'划转成功' => 'Transferred',
'类型错误' => 'ERROR',
];
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+110
View File
@@ -0,0 +1,110 @@
<?php
return [
'法币账户转到APECbot' => 'Fiat to APECbot',
'APECbot转到法币账户' => 'APECbot to Fiat',
'余额不足' => 'Low Blance',
'提币出账' => 'Withdraw',
'合约交易保证金' => 'Deposit',
'合约交易手续费' => 'Charge',
'合约交易平仓' => 'Close',
'合约交易保证金及手续费' => 'Deposit & Charge',
'周期持仓' => 'Position',
'周期持仓取消' => 'Cancel',
'币币交易买入' => 'Buy',
'币币交易卖出' => 'Sell',
'币币交易撤销买单' => 'Cancel',
'C2C挂卖' => 'Sell',
'手续费扣除' => 'Charged',
'货币出售' => 'Sell',
'挂卖单撤回' => 'Canceled',
'取消订单' => 'Cancel Order',
'C2C购买交易' => 'Buy',
'量化卖出' => 'Sell',
'扣取信誉值' => 'Charged',
'量化补仓' => 'Adding',
'量化入场' => 'Join',
'直推获取信誉值' => 'Invite Rewards',
'团队获取信誉值' => 'Team Rewards',
'trc20-USDT充值' => 'trc20-USDT Deposit',
'erc20-USDT充值' => 'erc20-USDT Deposit',
'提币APT手续费' => 'Charged APT',
'周期持仓获利' => 'Position profit',
'周期持仓平仓' => 'Liquidation',
'周期持仓亏损' => 'Position loss',
'现货账户转到量化账户' => 'Transfer',
'现货账户转到法币账户' => 'Transfer',
'量化账户转到现货账户' => 'Transfer',
'法币账户转到现货账户' => 'Transfer',
'现货账户' => 'Spot account',
'法币账户' => 'Fiat Account',
'量化账户' => 'Quantitative account',
'合约交易平仓亏损' => 'Contract loss',
'合约交易平仓盈利' => 'Contract profit',
'后台充值' => 'Recharge',
'锁仓' => 'Lock up',
'天使投资' => 'Angel investment',
'日息释放' => 'Daily interest release',
'本金释放' => 'Principal release',
'天使直推' => 'Angel push',
'邮箱验证失败' => 'Email verification failed',
'手机号验证失败' => 'Phone number verification failed',
'谷歌验证失败' => 'Google verification failed',
'请输入私钥' => 'Please enter the private key',
'请输入验证码' => 'Please Enter OTP',
'请勿重复绑定' => 'Do not bind repeatedly',
'绑定成功' => 'Bind successfully',
'绑定失败' => 'Binding failed',
'请先绑定谷歌验证' => 'Please bind Google verification first',
'暂未绑定' => 'Not yet bound',
'解绑成功' => 'Unbind successfully',
'解绑失败' => 'Unbinding failed',
'验证失败' => 'verification failed',
'根据当地区法律规定,暂不支持该地区注册' => 'According to local laws and regulations, registration in this region is temporarily not supported',
'即将开放,请耐心等待!' => 'It will open soon, please be patient!',
'24小时限额' => '24 hour limit',
'第一阶段' => 'First Round',
'第二阶段' => 'Second Round',
'第三阶段' => 'The third phase',
'第四阶段' => 'Fourth stage',
'第五阶段' => 'The fifth stage',
'请输入有效数量' => 'Please enter a valid quantity',
'剩余数量不足' => 'Insufficient quantity remaining',
'最低投资:' => 'Minimum investment',
'本轮投资上限' => 'Upper limit of current round of investment',
'参与失败' => 'Participation failed',
'记录不存在' => 'Record does not exist',
'第一年' => '1st Year',
'第二年' => '2nd Year',
'第三年' => '3rd Year',
'第四年' => '4th Year',
'满五年' => '5th Year',
'盲盒抽奖' => 'Blind Box Draw',
'您今日已经签到过了' => 'You have signed in today',
'该邮箱已被绑定' => 'The mailbox has been bound',
'验证码错误' => 'Verification code error',
'该手机已被绑定' => 'The phone has been bound',
'您有未成交的交易,暂不可修改' => 'You have an unexecuted transaction, which cannot be modified for the time being',
'已被注册' => 'Registered',
'产品不存在或已下架' => 'The product does not exist or has been taken off the shelf',
'最低投资数量:' => 'Minimum investment quantity:',
'最高投资数量:' => 'Maximum investment quantity:',
'产品投资' => 'Product investment',
'网络错误,请稍后再试!' => 'Network error, please try again later!',
'理财本金退还' => 'Refund of financial principal',
'理财利息' => 'Financial interest',
'理财利息' => '理财利息',
'请填写开户行' => 'Please fill in the Bank of deposit',
'请填写银行卡号' => 'Please fill in the bank card number',
'请选择银行' => 'Please select a bank',
'请选择提现的银行卡' => 'Please select the bank card for withdrawal',
'在线充值' => 'Online recharge',
'后台扣除' => 'Gold withdrawal',
'后台扣除' => 'Gold withdrawal',
'证件号已存在' => 'Certificate number already exists',
'限价模式,请输入正确价格' => 'Price limit mode, please enter correct price',
];
+26
View File
@@ -0,0 +1,26 @@
<?php
return [
"请先完成实名认证" => "Please Complete KYC Verification",
"请选择交易模式" => "Select Type Trading",
"限价模式,请输入价格" => "LimitedEnter the Price",
"请选择交易币种" => "Select Token",
"该交易币种已下架或不存在" => "Unavailable Token",
"请选择交易方向" => "Please Select Side",
"请输入交易数量" => "Please Enter Amount",
"请选择交易倍数" => "Please Select Cast",
"请选择正确的交易倍数" => "Invalid Selected Cast",
"操作频繁" => "Operations Frequent",
"账号余额不足" => "Low Balance",
"系统繁忙" => "System Pending",
"提交成功" => "Succeed",
"请选择设置的合约订单" => "Please Select Futures Order has been Set",
"合约订单不存在或已平仓" => "Order Unavailable or Closed",
"请设置止盈价格" => "Please Setting Takeprofit's Price",
"请设置止损价格" => "Please Setting Stop-loss Price",
"设置成功" => "Succed",
"请选择合约订单" => "Please Futures Order",
"已平仓" => "Closed",
"已撤销" => "Canceled",
"未查询到币种信息" => "Invalid",
];
+19
View File
@@ -0,0 +1,19 @@
<?php
return [
"请选择交易对" => "Select Pair",
"请输入正确的交易数量" => "Please Enter Correct Amount",
"请选择交易周期" => "Please Select Period Time",
"请选择交易涨跌" => "Please Select the Changes",
"请先完成实名认证" => "Please Complete KYC Verification",
"交易对不存在" => "Invalid Pair",
"交易周期错误" => "Error Period Time",
"账号余额不足" => "Low Balance",
"该周期需拥有资产:" => "Asset Unavailable:",
"操作频繁" => "Operations Frequent",
"提交成功" => "Succeed",
"请选择要取消的订单" => "Please Select the Oder You would Like to Cancel",
"订单不存在" => "Invalid Order",
"订单超时,不能取消" => "Order has been pastcannot cancel",
"系统繁忙" => "System Busy",
];
+20
View File
@@ -0,0 +1,20 @@
<?php
return [
"内容不存在" => "Invalid Content",
"请选择要查询的榜单" => "Please Select Ranking",
"私募不存在" => "Invalid ICO",
"非预约时间" => "Invalid Appoint Time",
"请勿重复预约" => "Please Do Not Repeat Appoinment",
"预约成功" => "Appoinment Succeed",
"交易密码错误" => "Trading Password Wrong",
"非私募时间" => "Invalid ICO Time",
"请输入有效数量" => "Please Enter Correct Amount",
"可私募数量不足" => "Invalid ICO Volume",
"余额不足" => "Balance Low",
"操作频繁" => "Operations Frequent",
"私募成功" => "Succeed",
"周期不存在" => "Invalid Period Time",
"锁仓成功" => "Succeed",
"记录不存在" => "Invalid History",
];
+19
View File
@@ -0,0 +1,19 @@
<?php
return [
"请选择交易模式" => "Please Select Exchange Type",
"请先完成实名认证" => "Please Complete KYC Verification",
"请选择交易币种" => "Please Select Token",
"该交易币种已下架或不存在" => "Invalid Token",
"限价模式,请输入价格" => "Please Enter the Price",
"请选择交易方向" => "Please Select Side",
"请输入交易数量" => "Please Enter Amount",
"操作频繁" => "Operations Frequent",
"余额不足" => "Balance Low",
"系统繁忙" => "System Busy",
"提交成功" => "Succeed",
"请选择交易单" => "Please Select Trading",
"交易单不存在或已完全成交" => "Invalid Order",
"已撤销" => "Canceled",
];
+50
View File
@@ -0,0 +1,50 @@
<?php
return [
"数量错误" => "Amount Error",
"请先完成实名认证" => "Please Complete KYC Verification",
"请选择收款账户" => "Please Select Account",
"金额输入错误" => "Amount Error",
"交易密码错误" => "Trading Password Error",
"暂不支持此法币" => "Unavailable Now",
"最低挂单数量为" => "Min as",
"最高挂单数量为" => "Max as",
"选择的收款方式有误" => "Payment Method Error",
"操作频繁" => "Operations Frequent",
"余额不足" => "Balance Low",
"发布成功" => "Succeed",
"发布失败" => "Failed",
"选择的支付方式有误" => "Error Payment Method",
"手续费不足" => "Charge Balance Low",
"输入有误" => "Error",
"订单不存在" => "Invalid Order",
"不可交易自己订单" => "Error",
"该订单已被交易" => "Order has been Trade",
"订单错误" => "Error Order",
"您有一笔订单正在交易中,请先完成" => "Please Complete Your Order",
"交易限制" => "Trading Restrictions",
"订单数量不足" => "Order Amount Low",
"限额" => "Limit",
"下单成功" => "Succeed",
"下单失败" => "Failed",
"非法操作" => "Error Operation",
"该订单不可撤回" => "Order Cannot Cancel",
"撤回成功" => "Canceled",
"撤回失败" => "Failed",
"已付款不可取消" => "Cannot Cancel",
"非法请求" => "Error Request",
"今日取消次数已达上线" => "Cancellation has been reached the limits",
"取消成功" => "Canceled",
"网络错误" => "Network Error",
"请上传支付凭证" => "Please Upload Proof of Payment",
"请勿重复操作" => "Please do not Repeat the Operation",
"网络连接失败" => "Network Failures",
"交易成功" => "Succeed",
"请输入申述内容" => "Please Enter Dispute's Message",
"请上传凭证附件" => "Please Upload the Image/Photo",
"此订单不可申述" => "Cannot be Dispute",
"申述成功" => "Disputed",
"申述不存在" => "Invalid Dispute",
"该申述订单已被处理" => "Dispute has been Processed",
"提交成功" => "Succeed",
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
"即将开放,请耐心等待!" => "Coming Soon,Please be Patient!",
];
+28
View File
@@ -0,0 +1,28 @@
<?php
return [
"请输入姓名" => "Please Enter Your Name",
"请输入证件证号" => "Please Enter ID Number",
"您已完成初级认证" => "You have been Completed Level 1",
"提交成功" => "Succeed",
"系统繁忙" => "System Busy",
"请上传正面证件照" => "Please Upload Front ID Image",
"请上传背面证件照" => "Please Upload Back ID Image",
"请先完成初级认证" => "Please Complete Level 1 Verify",
"您已完成高级认证" => "You have been Completed Higher Level Verify",
"昵称已存在" => "Nickname has been used",
"请输入有效地址" => "Please Enter Valid Address",
"请输入备注信息" => "Please Enter Remarks Message",
"请选择币种类型" => "Please Select Token",
"添加成功" => "Succeed",
"地址不存在" => "Invalid Address",
"修改成功" => "Edit Successfully",
"删除成功" => "Deleted",
"请填写姓名" => "Please Enter Name",
"请填写银行卡号" => "Please Enter Bank Card Number",
"请填写开户行" => "Please Enter Bank Name",
"请填写开户支行" => "Please Enter Bank Branch",
"收款方式不存在" => "Invalid Payment Method",
"修改失败" => "Failed",
"添加失败" => "Failed",
"内容不存在" => "Invalid Content",
];
+12
View File
@@ -0,0 +1,12 @@
<?php
return [
'发送频繁' => "Operation Frequent",
'已被注册' => 'Has been registered',
'已被占用' => 'Has been used',
'请在后台插件管理安装短信验证插件' =>'Please install the SMS verification plug-in management',
'发送成功' => 'Sent',
'未注册' => 'Unregister',
'发送失败' => 'Failed',
];
+22
View File
@@ -0,0 +1,22 @@
<?php
return [
"请输入要搜索的币种" => "Please Enter Token Name",
"币种不存在" => "Invalid Token",
"请选择要设置的币种" => "Please Select a Token",
"请先完成实名认证" => "Please Complete KYC Verification",
"币种已下架或不存在" => "Invalid Token",
"最低买单数量为" => "Min Buy Amount as",
"最高做单数量" => "Max Long Amount",
"信誉值不足,请充值" => "Fee LowPlease Reload",
"提交成功" => "Succeed",
"系统繁忙" => "System Busy",
"请选择操作币种" => "Please Select a Token",
"操作频繁" => "Operations Frequent",
"已清仓,请查看交易记录详情" => "ClosedPlease Check History",
"清仓失败" => "Closing Failed",
"请输入补仓数量" => "Please Enter the Amount",
"交易币种不存在" => "Invalid Token",
"请开启策略" => "Please On Stategy",
"加仓成功" => "Succeed",
"请输入设置的补仓最低余额限制" => "Please Enter Minimum Adding Volume",
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
"系统繁忙" => "System Busy",
];
+30
View File
@@ -0,0 +1,30 @@
<?php
return [
'操作频繁' => 'Operations Frequent',
'请输入邀请码' => 'Please Enter Invitation Code',
'推荐码不存在' => 'Invalid Invite Code',
'创建钱包失败 请联系客服' => 'Failed Please Contact Our Customer Service',
'请输入正确的姓名' => 'Invalid Name',
'请输入正确的身份证号' => 'Invalid Country ID',
'您已实名' => 'Verified',
'提交成功' => 'Succeed',
'系统繁忙' => 'System Busy',
'请输入原始密码' => 'Enter Old Password',
'请选择修改的密码类型' => 'Please Select Password Type',
'请输入新密码' => 'Enter New Password',
'原始密码错误' => 'Wrong Password',
'新密码与旧密码相同,请重新输入' => 'Do Not Repeat Previous PasswordPlease Re-Enter',
'请上传身份证正面照' => 'Please Upload Your ID Front Image',
'请上传身份证背面照' => 'Please Upload Your ID Back Image',
'请输入账号密码' => 'Please Enter Password',
'登录成功' => 'Login Successful',
'注册成功' => 'Registered',
'推出成功' => 'Succeed',
'请输入完整信息' => 'Please Enter Complete Detail',
'邮箱错误' => 'Invalid Email Address',
'用户不存在' => 'Invalid User ID',
'验证码错误' => 'Invalid OTP',
'重置密码成功' => 'Password Reset Successful',
];
+11
View File
@@ -0,0 +1,11 @@
<?php
return [
"邮箱已经被占用" => "Email has been used",
"用户名已经被占用" => "User ID has been used",
"昵称已经被占用" => "Nickname has been used",
"该手机号已经占用" => "Phone number has been used",
"手机号不存在" => "Invalid Phone Number",
"邮箱不存在" => "Invalid Email Address",
"验证码不正确" => "Error OTP",
];
+38
View File
@@ -0,0 +1,38 @@
<?php
return [
'请输入正确的地址' => 'Please Enter Valid Address',
'请输入正确的数量' => 'Please Enter Valid Amount',
'请输入交易密码' => 'Please Entet Trading Password',
'请输入验证码' => 'Please Enter OTP',
'请选择提币的种类' => 'Please Select Token',
'手机验证码不正确' => 'OTP Code Wrong',
'交易密码错误' => 'Trading Password Wrong',
'操作频繁' => 'Operations Frequent',
'提币限额为' => 'Maximunm',
'余额不足' => 'Low Blance',
'提交成功' => 'Succeed',
'系统繁忙' => 'System Busy',
'请输入备注' => 'Please Enter Remarks',
'抱歉,改地址信息不存在' => 'SorryInvalid Address',
'请选择正确的地址' => 'Please Select Valid Address',
'请输入转入地址' => 'Please Enter Deposit Address',
'请输入转入数量' => 'Please Enter Amount',
'请输入交易编号' => 'Please Enter Order Number',
'交易编号无效' => 'Invalid Order Number',
'提交成功,请等待审核' => 'Successful,Wait for Verify',
'请输入正确的互转用户' => 'Please Enter Valid User ID',
'账户不存在' => 'Invalid ID',
'互转通道已关闭' => 'Transer Closed',
'互转限额为' => 'Limits',
'请完成实名' => 'Please Complete KYC Verification',
'不可同类型划转' => 'Error Transfer',
'请输入有效数量' => 'Please Enter Valid Amount',
'该币种不支持划转' => 'Transfer Unsupported',
'请选择正确划转类型' => 'Please Select Valid Transfer Type',
'划转成功' => 'Transferred',
'类型错误' => 'ERROR',
];
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+98
View File
@@ -0,0 +1,98 @@
<?php
//法语
return [
'法币账户转到量化账户' => 'Transfert du compte en monnaie française au compte quantitatif',
'量化账户转到法币账户' => 'Transfert du compte de quantification au compte en monnaie française',
'余额不足' => 'Solde insuffisant',
'提币出账' => 'Retrait de la monnaie',
'合约交易保证金' => 'Marge de négociation contractuelle',
'合约交易手续费' => 'Frais de transaction contractuels',
'合约交易平仓' => 'Clôture des opérations contractuelles',
'合约交易保证金及手续费' => 'Marge et frais de transaction contractuels',
'周期持仓' => 'Position cyclique',
'周期持仓取消' => 'Annulation de la position du cycle',
'币币交易买入' => 'Achat de devises',
'币币交易卖出' => 'Vente de devises',
'币币交易撤销买单' => 'Annulation de la transaction en monnaie',
'C2C挂卖' => 'C2c pendaison',
'手续费扣除' => 'Déduction des frais de manutention',
'货币出售' => 'Vente de devises',
'挂卖单撤回' => 'Retrait de l\'ordre de vente',
'取消订单' => 'Annuler la commande',
'C2C购买交易' => 'C2c transaction d\'achat',
'量化卖出' => 'Ventes quantifiées',
'扣取信誉值' => 'Déduire la valeur de réputation',
'量化补仓' => 'Reconstitution quantitative des stocks',
'量化入场' => 'Accès quantifié',
'直推获取信誉值' => 'Pousser directement pour obtenir la valeur de réputation',
'团队获取信誉值' => 'L\'équipe obtient une valeur de réputation',
'trc20-USDT充值' => 'Trc20 usdt recharge',
'erc20-USDT充值' => 'Recharge erc20 usdt',
'提币APY手续费' => 'Frais de manutention apy pour le retrait des pièces',
'周期持仓获利' => 'Bénéfice de position du cycle',
'周期持仓平仓' => 'Clôture périodique des positions',
'周期持仓亏损' => 'Perte de position cyclique',
'现货账户转到量化账户' => 'Transfert du compte au comptant au compte de quantification',
'现货账户转到法币账户' => 'Transfert du compte au comptant au compte en monnaie française',
'量化账户转到现货账户' => 'Transfert du compte de quantification au compte au comptant',
'法币账户转到现货账户' => 'Transfert du compte en monnaie française au compte au comptant',
'现货账户' => 'Spot account',
'法币账户' => 'Conto di valuta legale',
'量化账户' => 'Conto quantitativo',
'合约交易平仓亏损' => 'Perte de contrat',
'合约交易平仓盈利' => 'Bénéfice du contrat',
'后台充值' => 'Recharger',
'锁仓' => 'Enfermer',
'天使投资' => 'Investissement providentiel',
'日息释放' => 'Libération des intérêts quotidiens',
'本金释放' => 'Sortie principale',
'天使直推' => 'Poussée dange',
'邮箱验证失败' => 'Échec de la vérification de le-mail',
'手机号验证失败' => 'Échec de la vérification du numéro de téléphone',
'谷歌验证失败' => 'Échec de la vérification Google',
'请输入私钥' => 'Veuillez saisir la clé privée',
'请输入验证码' => 'veuillez entrer le code de vérification',
'请勿重复绑定' => 'Ne pas lier à plusieurs reprises',
'绑定成功' => 'Lier avec succès',
'绑定失败' => 'Échec de la liaison',
'请先绑定谷歌验证' => 'Veuillez dabord lier la vérification Google',
'暂未绑定' => 'Pas encore lié',
'解绑成功' => 'Délier avec succès',
'解绑失败' => 'Échec de la déliaison',
'验证失败' => 'échec de la vérification',
'根据当地区法律规定,暂不支持该地区注册' => "Conformément aux lois et réglementations locales, l'enregistrement dans cette région n'est temporairement pas pris en charge",
'即将开放,请耐心等待!' => 'Il ouvrira bientôt, sil vous plaît soyez patient!',
'24小时限额' => 'limite de 24 heures',
'第一阶段' => 'Le premier stade',
'第二阶段' => 'Deuxième étape',
'第三阶段' => 'La troisième phase',
'第四阶段' => 'Quatrième étape',
'第五阶段' => 'La cinquième étape',
'请输入有效数量' => 'Veuillez entrer une quantité valide',
'剩余数量不足' => 'Quantité restante insuffisante',
'最低投资:' => 'Investissement minimum :',
'本轮投资上限' => 'Vous avez dépassé la limite dinvestissement pour ce tour',
'参与失败' => 'Échec de la participation',
'记录不存在' => 'Lenregistrement nexiste pas',
'第一年' => '1 ère année',
'第二年' => '2e année',
'第三年' => '3ème année',
'第四年' => '4e année',
'满五年' => '5e année',
'盲盒抽奖' => 'Tirage au sort à laveugle',
'您今日已经签到过了' => 'Vous vous êtes connecté aujourdhui',
'该邮箱已被绑定' => 'La boîte aux lettres a été liée',
'验证码错误' => 'Erreur de code de vérification',
'该手机已被绑定' => 'Le téléphone a été lié',
'您有未成交的交易,暂不可修改' => 'Vous avez une transaction non exécutée, qui ne peut pas être modifiée pour le moment',
'产品不存在或已下架' => 'Le produit nexiste pas ou a été retiré de l’étagère',
'最低投资数量:' => 'Investissement minimum:',
'最高投资数量:' => 'Investissement maximal:',
'产品投资' => 'Investissement dans les produits',
'网络错误,请稍后再试!' => 'Erreur réseau, Veuillez réessayer plus tard!',
'理财本金退还' => 'Remboursement du principal de gestion financière',
'理财利息' => 'Intérêts financiers',
'在线充值' => 'Online recharge',
];
+26
View File
@@ -0,0 +1,26 @@
<?php
return [
'请先完成实名认证' => 'Veuillez d\'abord compléter l\'authentification du nom réel',
'请选择交易模式' => 'Veuillez sélectionner le mode de transaction',
'限价模式,请输入价格' => 'Mode limite de prix, veuillez entrer le prix',
'请选择交易币种' => 'Veuillez sélectionner la devise de transaction',
'该交易币种已下架或不存在' => 'La monnaie de transaction est hors stock ou n\'existe pas',
'请选择交易方向' => 'Veuillez sélectionner la direction de la transaction',
'请输入交易数量' => 'Veuillez saisir la quantité de transaction',
'请选择交易倍数' => 'Veuillez sélectionner le multiple de transaction',
'请选择正确的交易倍数' => 'Veuillez sélectionner le bon multiple de transaction',
'操作频繁' => 'Opérations fréquentes',
'账号余额不足' => 'Solde insuffisant du compte',
'系统繁忙' => 'Système occupé',
'提交成功' => 'Soumis avec succès',
'请选择设置的合约订单' => 'Veuillez sélectionner l\'ordre contractuel défini',
'合约订单不存在或已平仓' => 'L\'ordre contractuel n\'existe pas ou est fermé',
'请设置止盈价格' => 'Veuillez fixer le prix de fin de bénéfice',
'请设置止损价格' => 'Veuillez fixer le prix d\'arrêt des pertes',
'设置成功' => 'Configuration réussie',
'请选择合约订单' => 'Veuillez sélectionner une commande contractuelle',
'已平仓' => 'Position fermée',
'已撤销' => 'Annulé',
'未查询到币种信息' => 'Aucune information sur la devise trouvée',
];
+18
View File
@@ -0,0 +1,18 @@
<?php
return [
'请选择交易对' => 'Veuillez sélectionner une paire de transactions',
'请输入正确的交易数量' => 'Veuillez saisir le nombre correct de transactions',
'请选择交易周期' => 'Veuillez sélectionner la période de transaction',
'请选择交易涨跌' => 'Veuillez sélectionner les fluctuations des échanges',
'请先完成实名认证' => 'Veuillez d\'abord compléter l\'authentification du nom réel',
'交易对不存在' => 'La paire de transactions n\'existe pas',
'交易周期错误' => 'Erreur de cycle de transaction',
'账号余额不足' => 'Solde insuffisant du compte',
'操作频繁' => 'Opérations fréquentes',
'提交成功' => 'Soumis avec succès',
'请选择要取消的订单' => 'Veuillez sélectionner la commande à annuler',
'订单不存在' => 'L\'ordre n\'existe pas',
'订单超时,不能取消' => 'La commande a expiré et ne peut être annulée',
'系统繁忙' => 'Système occupé',
];
+20
View File
@@ -0,0 +1,20 @@
<?php
return [
'内容不存在' => 'Le contenu n\'existe pas',
'请选择要查询的榜单' => 'Veuillez sélectionner la liste à interroger',
'私募不存在' => 'Le placement privé n\'existe pas',
'非预约时间' => 'Temps non réservé',
'请勿重复预约' => 'Ne pas répéter la réservation',
'预约成功' => 'Rendez - vous réussi',
'交易密码错误' => 'Erreur de mot de passe de transaction',
'非私募时间' => 'Temps non privé',
'请输入有效数量' => 'Veuillez saisir une quantité valide',
'可私募数量不足' => 'Nombre insuffisant de placements privés',
'余额不足' => 'Solde insuffisant',
'操作频繁' => 'Opérations fréquentes',
'私募成功' => 'Placement privé réussi',
'周期不存在' => 'Le cycle n\'existe pas',
'锁仓成功' => 'Verrouillage réussi',
'记录不存在' => 'L\'enregistrement n\'existe pas',
];
+19
View File
@@ -0,0 +1,19 @@
<?php
return [
'请选择交易模式' => 'Veuillez sélectionner le mode de transaction',
'请先完成实名认证' => 'Veuillez d\'abord compléter l\'authentification du nom réel',
'请选择交易币种' => 'Veuillez sélectionner la devise de transaction',
'该交易币种已下架或不存在' => 'La monnaie de transaction est hors stock ou n\'existe pas',
'限价模式,请输入价格' => 'Mode limite de prix, veuillez entrer le prix',
'请选择交易方向' => 'Veuillez sélectionner la direction de la transaction',
'请输入交易数量' => 'Veuillez saisir la quantité de transaction',
'操作频繁' => 'Opérations fréquentes',
'余额不足' => 'Solde insuffisant',
'系统繁忙' => 'Système occupé',
'提交成功' => 'Soumis avec succès',
'请选择交易单' => 'Veuillez sélectionner la Feuille de transaction',
'交易单不存在或已完全成交' => 'L\'ordre de transaction n\'existe pas ou a été entièrement exécuté',
'已撤销' => 'Annulé',
];
+50
View File
@@ -0,0 +1,50 @@
<?php
return [
'数量错误' => 'Erreur de quantité',
'请先完成实名认证' => 'Veuillez d\'abord compléter l\'authentification du nom réel',
'请选择收款账户' => 'Veuillez sélectionner un compte de collecte',
'金额输入错误' => 'Erreur d\'entrée du montant',
'交易密码错误' => 'Erreur de mot de passe de transaction',
'暂不支持此法币' => 'Cette monnaie légale n\'est pas prise en charge pour le moment',
'最低挂单数量为' => 'La quantité minimale d\'inscription est:',
'最高挂单数量为' => 'La quantité maximale d\'inscription est:',
'选择的收款方式有误' => 'Mauvaise méthode de collecte sélectionnée',
'操作频繁' => 'Opérations fréquentes',
'余额不足' => 'Solde insuffisant',
'发布成功' => 'Publié avec succès',
'发布失败' => 'Échec de la publication',
'选择的支付方式有误' => 'Mauvaise méthode de paiement choisie',
'手续费不足' => 'Frais de manutention insuffisants',
'输入有误' => 'Erreur d\'entrée',
'订单不存在' => 'L\'ordre n\'existe pas',
'不可交易自己订单' => 'Ne pas échanger vos propres commandes',
'该订单已被交易' => 'La commande a été échangée',
'订单错误' => 'Erreur de commande',
'您有一笔订单正在交易中,请先完成' => 'Vous avez une commande en cours, veuillez la remplir en premier',
'交易限制' => 'Restrictions commerciales',
'订单数量不足' => 'Quantité de commande insuffisante',
'限额' => 'Limites',
'下单成功' => 'Commande réussie',
'下单失败' => 'Échec de la commande',
'非法操作' => 'Opérations illégales',
'该订单不可撤回' => 'L\'ordre est irrévocable',
'撤回成功' => 'Retrait réussi',
'撤回失败' => 'Échec du retrait',
'已付款不可取消' => 'Paiement non annulable',
'非法请求' => 'Demandes illégales',
'今日取消次数已达上线' => 'Annulation en ligne aujourd\'hui',
'取消成功' => 'Annulation réussie',
'网络错误' => 'Erreur de réseau',
'请上传支付凭证' => 'Veuillez télécharger le bon de paiement',
'请勿重复操作' => 'Ne pas répéter',
'网络连接失败' => 'La connexion réseau a échoué',
'交易成功' => 'Marché conclu',
'请输入申述内容' => 'Veuillez entrer le contenu de l\'appel',
'请上传凭证附件' => 'Veuillez télécharger la pièce jointe du bon',
'此订单不可申述' => 'Cette commande n\'est pas recevable',
'申述成功' => 'Les représentations ont été acceptées.',
'申述不存在' => 'Les représentations n\'existent pas',
'该申述订单已被处理' => 'L\'ordonnance de représentation a été traitée',
'提交成功' => 'Soumis avec succès',
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
'即将开放,请耐心等待!' => 'Bientôt ouvert, veuillez patienter!',
];
+28
View File
@@ -0,0 +1,28 @@
<?php
return [
'请输入姓名' => 'Veuillez saisir un nom',
'请输入证件证号' => 'Veuillez saisir le numéro de carte d\'identité',
'您已完成初级认证' => 'Vous avez complété la certification initiale',
'提交成功' => 'Soumis avec succès',
'系统繁忙' => 'Système occupé',
'请上传正面证件照' => 'Veuillez télécharger la photo d\'identité positive',
'请上传背面证件照' => 'Veuillez télécharger la photo d\'identité au verso',
'请先完成初级认证' => 'Veuillez d\'abord compléter la certification primaire',
'您已完成高级认证' => 'Vous avez complété la certification avancée',
'昵称已存在' => 'Le surnom existe déjà',
'请输入有效地址' => 'Veuillez saisir une adresse valide',
'请输入备注信息' => 'Veuillez saisir les commentaires',
'请选择币种类型' => 'Veuillez sélectionner le type de devise',
'添加成功' => 'Ajouté avec succès',
'地址不存在' => 'L\'adresse n\'existe pas',
'修改成功' => 'Modification réussie',
'删除成功' => 'Suppression réussie',
'请填写姓名' => 'Veuillez remplir le nom',
'请填写银行卡号' => 'Veuillez remplir le numéro de carte bancaire',
'请填写开户行' => 'Veuillez remplir la Banque de dépôt',
'请填写开户支行' => 'Veuillez remplir la Sous - direction de l\'ouverture du compte',
'收款方式不存在' => 'La méthode de collecte n\'existe pas',
'修改失败' => 'Échec de la modification',
'添加失败' => 'Impossible d\'ajouter',
'内容不存在' => 'Le contenu n\'existe pas',
];
+12
View File
@@ -0,0 +1,12 @@
<?php
return [
'发送频繁' => 'Envoyer fréquemment',
'已被注册' => 'Enregistré',
'已被占用' => 'Occupé',
'请在后台插件管理安装短信验证插件' => 'Veuillez installer le plug - in de vérification SMS dans la gestion du plug - in de fond',
'发送成功' => 'Envoyé avec succès',
'未注册' => 'Non enregistré',
'发送失败' => 'Échec de l\'envoi',
];
+22
View File
@@ -0,0 +1,22 @@
<?php
return [
'请输入要搜索的币种' => 'Veuillez saisir la devise à rechercher',
'币种不存在' => 'La monnaie n\'existe pas',
'请选择要设置的币种' => 'Veuillez sélectionner la devise à définir',
'请先完成实名认证' => 'Veuillez d\'abord compléter l\'authentification du nom réel',
'币种已下架或不存在' => 'Monnaie hors étagère ou inexistante',
'最低买单数量为' => 'La quantité minimale à payer est:',
'最高做单数量' => 'Quantité maximale de fabrication',
'信誉值不足,请充值' => 'Valeur de réputation insuffisante, veuillez recharger',
'提交成功' => 'Soumis avec succès',
'系统繁忙' => 'Système occupé',
'请选择操作币种' => 'Veuillez sélectionner la devise d\'opération',
'操作频繁' => 'Opérations fréquentes',
'已清仓,请查看交易记录详情' => 'Position fermée, veuillez vérifier les détails de la transaction',
'清仓失败' => 'Échec de la liquidation',
'请输入补仓数量' => 'Veuillez entrer la quantité de réapprovisionnement',
'交易币种不存在' => 'La monnaie de transaction n\'existe pas',
'请开启策略' => 'Veuillez activer la politique',
'加仓成功' => 'L\'entrepôt a été augmenté avec succès',
'请输入设置的补仓最低余额限制' => 'Veuillez saisir la limite minimale de solde de reconstitution établie',
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
"系统繁忙" => "系统繁忙",
];
+30
View File
@@ -0,0 +1,30 @@
<?php
return [
'操作频繁' => 'Opérations fréquentes',
'请输入邀请码' => 'Veuillez saisir le Code d\'invitation',
'推荐码不存在' => 'Le Code de référence n\'existe pas',
'创建钱包失败 请联系客服' => 'Impossible de créer le portefeuille veuillez contacter le service à la clientèle',
'请输入正确的姓名' => 'Veuillez saisir le nom correct',
'请输入正确的身份证号' => 'Veuillez saisir le bon numéro d\'identification',
'您已实名' => 'Vous avez un vrai nom',
'提交成功' => 'Soumis avec succès',
'系统繁忙' => 'Système occupé',
'请输入原始密码' => 'Veuillez saisir le mot de passe original',
'请选择修改的密码类型' => 'Veuillez sélectionner le type de mot de passe modifié',
'请输入新密码' => 'Veuillez saisir un nouveau mot de passe',
'原始密码错误' => 'Erreur de mot de passe original',
'新密码与旧密码相同,请重新输入' => 'Le nouveau mot de passe est le même que l\'ancien.',
'请上传身份证正面照' => 'Veuillez télécharger la photo de face de votre carte d\'identité',
'请上传身份证背面照' => 'Veuillez télécharger la photo au verso de votre carte d\'identité',
'请输入账号密码' => 'Veuillez saisir le mot de passe du compte',
'登录成功' => 'Connexion réussie',
'注册成功' => 'Inscription réussie',
'推出成功' => 'Lancement réussi',
'请输入完整信息' => 'Veuillez saisir les informations complètes',
'邮箱错误' => 'Erreur de boîte aux lettres',
'用户不存在' => 'L\'utilisateur n\'existe pas',
'验证码错误' => 'Erreur de code de vérification',
'重置密码成功' => 'Réinitialiser le mot de passe avec succès',
];
+11
View File
@@ -0,0 +1,11 @@
<?php
return [
'邮箱已经被占用' => 'La boîte aux lettres est déjà occupée',
'用户名已经被占用' => 'Le nom d\'utilisateur est déjà occupé',
'昵称已经被占用' => 'Le surnom est déjà occupé',
'该手机号已经占用' => 'Le numéro de téléphone est déjà occupé',
'手机号不存在' => 'Le numéro de téléphone n\'existe pas',
'邮箱不存在' => 'La boîte aux lettres n\'existe pas',
'验证码不正确' => 'Code de vérification incorrect',
];
+38
View File
@@ -0,0 +1,38 @@
<?php
return [
'请输入正确的地址' => 'Veuillez saisir l\'adresse correcte',
'请输入正确的数量' => 'Veuillez saisir la quantité correcte',
'请输入交易密码' => 'Veuillez saisir le mot de passe de la transaction',
'请输入验证码' => 'Veuillez saisir le Code de vérification',
'请选择提币的种类' => 'Veuillez sélectionner le type de retrait',
'手机验证码不正确' => 'Code de vérification du téléphone mobile incorrect',
'交易密码错误' => 'Erreur de mot de passe de transaction',
'操作频繁' => 'Opérations fréquentes',
'提币限额为' => 'Limite de retrait',
'余额不足' => 'Solde insuffisant',
'提交成功' => 'Soumis avec succès',
'系统繁忙' => 'Système occupé',
'请输入备注' => 'Veuillez entrer un commentaire',
'抱歉,改地址信息不存在' => 'Désolé, les informations de changement d\'adresse n\'existent pas',
'请选择正确的地址' => 'Veuillez sélectionner l\'adresse correcte',
'请输入转入地址' => 'Veuillez saisir l\'adresse de transfert',
'请输入转入数量' => 'Veuillez entrer la quantité transférée',
'请输入交易编号' => 'Veuillez saisir le numéro de transaction',
'交易编号无效' => 'Numéro de transaction non valable',
'提交成功,请等待审核' => 'Soumis avec succès, veuillez attendre l\'approbation',
'请输入正确的互转用户' => 'Veuillez saisir l\'utilisateur d\'échange correct',
'账户不存在' => 'Le compte n\'existe pas',
'互转通道已关闭' => 'Canal d\'interconnexion fermé',
'互转限额为' => 'La limite d\'échange est',
'请完成实名' => 'Veuillez remplir le vrai nom',
'不可同类型划转' => 'Ne peut pas être transféré du même type',
'请输入有效数量' => 'Veuillez saisir une quantité valide',
'改币种不支持划转' => 'Le transfert n\'est pas pris en charge pour le changement de devise',
'请选择正确划转类型' => 'Veuillez sélectionner le type de rotation correct',
'划转成功' => 'Transfert réussi',
'类型错误' => 'Mauvais type',
];
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+98
View File
@@ -0,0 +1,98 @@
<?php
//德语
return [
'法币账户转到量化账户' => 'Übertragung von Währungskonto auf Mengenkonto',
'量化账户转到法币账户' => 'Übertragung von quantitativem Konto auf das Währungskonto',
'余额不足' => 'Tut mir leid, dein Kredit ist knapp.',
'提币出账' => 'Auszahlung der Mittel',
'合约交易保证金' => 'Marge für Vertragstransaktionen',
'合约交易手续费' => 'Gebühr für Vertragstransaktionen',
'合约交易平仓' => 'Abschluss des Vertrags',
'合约交易保证金及手续费' => 'Marge des Vertrags und Bearbeitungsgebühr',
'周期持仓' => 'Periodische Lage',
'周期持仓取消' => 'Regelmäßige Positionsstornierung',
'币币交易买入' => 'Kauf von Währungstransaktionen',
'币币交易卖出' => 'Verkäufe des Devisenhandels',
'币币交易撤销买单' => 'Stornierung der Währungstransaktionen',
'C2C挂卖' => 'Verkauf von Hängen C2C',
'手续费扣除' => 'Abzug der Bearbeitungskosten',
'货币出售' => 'Verkauf von Bargeld',
'挂卖单撤回' => 'Widerruf des Aufhängungsantrags',
'取消订单' => 'Stornierung der Bestellung',
'C2C购买交易' => 'Kauftransaktion C2C',
'量化卖出' => 'Quantitative Verkäufe',
'扣取信誉值' => 'Wertminderung der Reputation',
'量化补仓' => 'Quantitative Auffüllung',
'量化入场' => 'Quantitative Zulassung',
'直推获取信誉值' => 'Erhalten Sie Reputation durch direkten Druck',
'团队获取信誉值' => 'Team gewinnt Reputation',
'trc20-USDT充值' => 'Trc20 usdt aufladen',
'erc20-USDT充值' => 'Erc20 usdt aufladen',
'提币APY手续费' => 'Apy Handling Gebühren für Währungsrücknahme',
'周期持仓获利' => 'Periodischer Gewinn',
'周期持仓平仓' => 'Regelmäßige Schließung',
'周期持仓亏损' => 'Periodische Positionsverluste',
'现货账户转到量化账户' => 'Übertragung von Spot-Konto auf Mengenkonto',
'现货账户转到法币账户' => 'Übertragung von Spot-Konto auf legales Währungskonto',
'量化账户转到现货账户' => 'Übertragung von quantitativem Konto auf Spot-Konto',
'法币账户转到现货账户' => 'Übertragung von legalem Währungskonto auf Spot-Konto',
'现货账户' => 'Spot Account',
'法币账户' => 'Rechtliches Währungskonto',
'量化账户' => 'Mengenmäßige Rechnung',
'合约交易平仓亏损' => 'Vertragsverlust',
'合约交易平仓盈利' => 'Vertragsgewinn',
'后台充值' => 'Aufladen',
'锁仓' => 'Abschließen',
'天使投资' => 'Engel Investition',
'日息释放' => 'Tägliche Zinsfreigabe',
'本金释放' => 'Hauptfreigabe',
'天使直推' => 'Engelsschub',
'邮箱验证失败' => 'E-Mail-Bestätigung fehlgeschlagen',
'手机号验证失败' => 'Verifizierung der Telefonnummer fehlgeschlagen',
'谷歌验证失败' => 'Google-Bestätigung fehlgeschlagen',
'请输入私钥' => 'Bitte geben Sie den privaten Schlüssel ein',
'请输入验证码' => 'Bitte Bestätigungscode eingeben',
'请勿重复绑定' => 'Nicht wiederholt binden',
'绑定成功' => 'Erfolgreich binden',
'绑定失败' => 'Bindung fehlgeschlagen',
'请先绑定谷歌验证' => 'Bitte zuerst die Google-Bestätigung binden',
'暂未绑定' => 'Noch nicht gebunden',
'解绑成功' => 'Bindung erfolgreich lösen',
'解绑失败' => 'Aufheben der Bindung fehlgeschlagen',
'验证失败' => 'Verifizierung fehlgeschlagen',
'根据当地区法律规定,暂不支持该地区注册' => 'Gemäß den lokalen Gesetzen und Vorschriften wird die Registrierung in dieser Region vorübergehend nicht unterstützt',
'即将开放,请耐心等待!' => 'Es wird bald geöffnet, bitte haben Sie etwas Geduld!',
'24小时限额' => '24-Stunden-Limit',
'第一阶段' => 'Die erste Stufe',
'第二阶段' => 'zweite Etage',
'第三阶段' => 'Die dritte Phase',
'第四阶段' => 'Vierte Stufe',
'第五阶段' => 'Die fünfte Etappe',
'请输入有效数量' => 'Bitte geben Sie eine gültige Menge ein',
'剩余数量不足' => 'Unzureichende Restmenge',
'最低投资:' => 'Mindestinvestition:',
'本轮投资上限' => 'Sie haben das Anlagelimit für diese Runde überschritten',
'参与失败' => 'Teilnahme fehlgeschlagen',
'记录不存在' => 'Datensatz existiert nicht',
'第一年' => '1. Jahr',
'第二年' => '2. Jahr',
'第三年' => '3. Jahr',
'第四年' => '4. Jahr',
'满五年' => '5. Jahr',
'盲盒抽奖' => 'Blind-Box-Draw',
'您今日已经签到过了' => 'Sie haben sich heute angemeldet',
'该邮箱已被绑定' => 'Der Briefkasten wurde gebunden',
'验证码错误' => 'Bestätigungscode-Fehler',
'该手机已被绑定' => 'Das Telefon wurde gebunden',
'您有未成交的交易,暂不可修改' => 'Sie haben eine nicht ausgeführte Transaktion, die derzeit nicht geändert werden kann',
'产品不存在或已下架' => 'The product does not exist or has been taken off the shelf',
'最低投资数量:' => 'Minimum investment quantity:',
'最高投资数量:' => 'Maximum investment quantity:',
'产品投资' => 'Product investment',
'网络错误,请稍后再试!' => 'Network error, please try again later!',
'理财本金退还' => 'Refund of financial principal',
'理财利息' => 'Financial interest',
'在线充值' => 'Online recharge',
];
+26
View File
@@ -0,0 +1,26 @@
<?php
return [
'请先完成实名认证' => 'Bitte füllen Sie zuerst die Echtname-Authentifizierung aus',
'请选择交易模式' => 'Bitte wählen Sie den Transaktionsmodus',
'限价模式,请输入价格' => 'Preis-Limit-Modus, bitte geben Sie den Preis ein',
'请选择交易币种' => 'Bitte wählen Sie Transaktionswährung',
'该交易币种已下架或不存在' => 'Die Transaktionswährung ist vom Regal entfernt oder existiert nicht',
'请选择交易方向' => 'Bitte wählen Sie die Handelsrichtung',
'请输入交易数量' => 'Bitte geben Sie die Transaktionsmenge ein',
'请选择交易倍数' => 'Bitte wählen Sie mehrere Transaktionen',
'请选择正确的交易倍数' => 'Bitte wählen Sie die korrekte Transaktion multiple',
'操作频繁' => 'Häufiger Betrieb',
'账号余额不足' => 'Unzureichender Kontostand',
'系统繁忙' => 'System besetzt',
'提交成功' => 'Eingereicht erfolgreich',
'请选择设置的合约订单' => 'Bitte wählen Sie den festgelegten Auftragsauftrag',
'合约订单不存在或已平仓' => 'Der Vertrag existiert nicht oder wurde geschlossen',
'请设置止盈价格' => 'Bitte setzen Sie den Preis',
'请设置止损价格' => 'Bitte setzen Sie den Stop-Loss-Preis',
'设置成功' => 'Setzt erfolgreich',
'请选择合约订单' => 'Bitte wählen Sie einen Auftrag',
'已平仓' => 'Geschlossene Position',
'已撤销' => 'aufgehoben',
'未查询到币种信息' => 'Keine Währungsinformationen gefunden',
];
+18
View File
@@ -0,0 +1,18 @@
<?php
return [
'请选择交易对' => 'Bitte wählen Sie Transaktionspaar',
'请输入正确的交易数量' => 'Bitte geben Sie die richtige Transaktionsmenge ein',
'请选择交易周期' => 'Bitte wählen Sie den Transaktionszyklus',
'请选择交易涨跌' => 'Bitte den Handelspreis auswählen',
'请先完成实名认证' => 'Bitte füllen Sie zuerst die Echtname-Authentifizierung aus',
'交易对不存在' => 'Das Transaktionspaar existiert nicht',
'交易周期错误' => 'Fehler beim Transaktionszyklus',
'账号余额不足' => 'Unzureichender Kontostand',
'操作频繁' => 'Häufiger Betrieb',
'提交成功' => 'Eingereicht erfolgreich',
'请选择要取消的订单' => 'Bitte wählen Sie die Bestellung zum Abbrechen',
'订单不存在' => 'Ordnung existiert nicht',
'订单超时,不能取消' => 'Timeout bestellen, kann nicht stornieren',
'系统繁忙' => 'System besetzt',
];
+20
View File
@@ -0,0 +1,20 @@
<?php
return [
'内容不存在' => 'Inhalt existiert nicht',
'请选择要查询的榜单' => 'Bitte wählen Sie die Liste für die Abfrage',
'私募不存在' => 'Private Platzierung existiert nicht',
'非预约时间' => 'Nicht planmäßige Zeit',
'请勿重复预约' => 'Wiederholen Sie den Termin nicht',
'预约成功' => 'Ernennung erfolgreich',
'交易密码错误' => 'Passwort-Fehler bei der Transaktion',
'非私募时间' => 'Nicht private Praktikumszeit',
'请输入有效数量' => 'Bitte geben Sie eine gültige Menge ein',
'可私募数量不足' => 'Unzureichende Privatplatzierung',
'余额不足' => 'Tut mir leid, dein Kredit ist knapp.',
'操作频繁' => 'Häufiger Betrieb',
'私募成功' => 'Private Platzierung erfolgreich',
'周期不存在' => 'Zyklus existiert nicht',
'锁仓成功' => 'Sperrlager erfolgreich',
'记录不存在' => 'Datensatz existiert nicht',
];
+19
View File
@@ -0,0 +1,19 @@
<?php
return [
'请选择交易模式' => 'Bitte wählen Sie den Transaktionsmodus',
'请先完成实名认证' => 'Bitte füllen Sie zuerst die Echtname-Authentifizierung aus',
'请选择交易币种' => 'Bitte wählen Sie Transaktionswährung',
'该交易币种已下架或不存在' => 'Die Transaktionswährung ist vom Regal entfernt oder existiert nicht',
'限价模式,请输入价格' => 'Preis-Limit-Modus, bitte geben Sie den Preis ein',
'请选择交易方向' => 'Bitte wählen Sie die Handelsrichtung',
'请输入交易数量' => 'Bitte geben Sie die Transaktionsmenge ein',
'操作频繁' => 'Häufiger Betrieb',
'余额不足' => 'Tut mir leid, dein Kredit ist knapp.',
'系统繁忙' => 'System besetzt',
'提交成功' => 'Eingereicht erfolgreich',
'请选择交易单' => 'Bitte wählen Sie das Transaktionsblatt',
'交易单不存在或已完全成交' => 'Der Transaktionsauftrag existiert nicht oder ist vollständig geschlossen',
'已撤销' => 'aufgehoben',
];
+50
View File
@@ -0,0 +1,50 @@
<?php
return [
'数量错误' => 'Fehler bei der Menge',
'请先完成实名认证' => 'Bitte füllen Sie zuerst die Echtname-Authentifizierung aus',
'请选择收款账户' => 'Bitte wählen Sie ein Sammelkonto aus',
'金额输入错误' => 'Fehler bei der Eingabe',
'交易密码错误' => 'Passwort-Fehler bei der Transaktion',
'暂不支持此法币' => 'Diese gesetzliche Währung wird derzeit nicht unterstützt',
'最低挂单数量为' => 'Die Mindestzahl der ausstehenden Bestellungen beträgt',
'最高挂单数量为' => 'Die maximale Anzahl anhängiger Bestellungen ist',
'选择的收款方式有误' => 'Falsche Sammelmethode ausgewählt',
'操作频繁' => 'Häufiger Betrieb',
'余额不足' => 'Tut mir leid, dein Kredit ist knapp.',
'发布成功' => 'Veröffentlicht erfolgreich',
'发布失败' => 'Veröffentlichung fehlgeschlagen',
'选择的支付方式有误' => 'Ausgewählt falsche Zahlungsmethode',
'手续费不足' => 'Unzureichende Bearbeitungsgebühren',
'输入有误' => 'Falsche Eingabe',
'订单不存在' => 'Ordnung existiert nicht',
'不可交易自己订单' => 'Du kannst deine eigenen Befehle nicht tauschen.',
'该订单已被交易' => 'Der Auftrag wurde abgewickelt',
'订单错误' => 'Fehler beim Bestellen',
'您有一笔订单正在交易中,请先完成' => 'Sie haben eine Bestellung im Rahmen der Transaktion.',
'交易限制' => 'Beschränkungen der Transaktion',
'订单数量不足' => 'Unzureichende Bestellmenge',
'限额' => 'Quote',
'下单成功' => 'Erfolg der Kasse',
'下单失败' => 'Befehl fehlgeschlagen',
'非法操作' => 'Illegaler Betrieb',
'该订单不可撤回' => 'Dieser Befehl ist unwiderruflich.',
'撤回成功' => 'Widerruf erfolgreich',
'撤回失败' => 'Abbruch fehlgeschlagen',
'已付款不可取消' => 'Die geleistete Zahlung kann nicht storniert werden',
'非法请求' => 'Illegaler Antrag',
'今日取消次数已达上线' => 'Die Anzahl der Stornierungen ist heute online erreicht',
'取消成功' => 'Stornierung erfolgreich',
'网络错误' => 'Fehler im Netzwerk',
'请上传支付凭证' => 'Bitte Zahlungsbeleg hochladen',
'请勿重复操作' => 'Nicht wiederholen',
'网络连接失败' => 'Netzwerkverbindung fehlgeschlagen',
'交易成功' => 'Erfolgreicher Handel',
'请输入申述内容' => 'Bitte geben Sie die Anweisung ein',
'请上传凭证附件' => 'Bitte laden Sie den Gutschein-Anhang hoch',
'此订单不可申述' => 'Diese Anordnung kann nicht geltend gemacht werden',
'申述成功' => 'Erfolgreiche Darstellung',
'申述不存在' => 'Der Anspruch existiert nicht',
'该申述订单已被处理' => 'Die Forderung wurde bearbeitet',
'提交成功' => 'Eingereicht erfolgreich',
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
'即将开放,请耐心等待!' => 'Es wird bald geöffnet, bitte warten Sie geduldig!',
];
+28
View File
@@ -0,0 +1,28 @@
<?php
return [
'请输入姓名' => 'Bitte geben Sie Ihren Namen ein',
'请输入证件证号' => 'Bitte geben Sie die ID-Nummer ein',
'您已完成初级认证' => 'Sie haben die Erstzertifizierung abgeschlossen',
'提交成功' => 'Eingereicht erfolgreich',
'系统繁忙' => 'System besetzt',
'请上传正面证件照' => 'Bitte ein positives ID-Foto hochladen',
'请上传背面证件照' => 'Bitte laden Sie das ID-Foto hinten hoch',
'请先完成初级认证' => 'Bitte füllen Sie zuerst die Erstzertifizierung aus.',
'您已完成高级认证' => 'Sie haben eine erweiterte Zertifizierung abgeschlossen',
'昵称已存在' => 'Spitzname existiert bereits',
'请输入有效地址' => 'Bitte geben Sie eine gültige Adresse ein',
'请输入备注信息' => 'Bitte Kommentare eingeben',
'请选择币种类型' => 'Bitte wählen Sie einen Währungstyp',
'添加成功' => 'Erfolgreich hinzugefügt',
'地址不存在' => 'Adresse existiert nicht',
'修改成功' => 'Geändert erfolgreich',
'删除成功' => 'Löschen erfolgreich',
'请填写姓名' => 'Bitte geben Sie Ihren Namen ein',
'请填写银行卡号' => 'Please fill in the bank card number',
'请填写开户行' => 'Bitte füllen Sie die Bank aus',
'请填写开户支行' => 'Bitte füllen Sie den Kontobereich aus',
'收款方式不存在' => 'Die Sammelmethode existiert nicht',
'修改失败' => 'Änderung fehlgeschlagen',
'添加失败' => 'Hinzufügen fehlgeschlagen',
'内容不存在' => 'Inhalt existiert nicht',
];
+12
View File
@@ -0,0 +1,12 @@
<?php
return [
'发送频繁' => 'Senden Sie häufig',
'已被注册' => 'Registriert',
'已被占用' => 'Besetzt',
'请在后台插件管理安装短信验证插件' => 'Bitte installieren Sie SMS-Verifizierungs-Plugin im Hintergrund-Plug-in-Management',
'发送成功' => 'Gesendet erfolgreich',
'未注册' => 'unregistriert',
'发送失败' => 'scheitern in senden',
];
+22
View File
@@ -0,0 +1,22 @@
<?php
return [
'请输入要搜索的币种' => 'Bitte geben Sie die gewünschte Währung ein',
'币种不存在' => 'Währung existiert nicht',
'请选择要设置的币种' => 'Bitte wählen Sie die zu setzende Währung',
'请先完成实名认证' => 'Bitte füllen Sie zuerst die Echtname-Authentifizierung aus',
'币种已下架或不存在' => 'Bargeld ist aus dem Regal oder existiert nicht',
'最低买单数量为' => 'Die Mindestrechnung beträgt',
'最高做单数量' => 'Maximale Bestellmenge',
'信誉值不足,请充值' => 'Unzureichender Kreditwert, bitte aufladen',
'提交成功' => 'Eingereicht erfolgreich',
'系统繁忙' => 'System besetzt',
'请选择操作币种' => 'Bitte wählen Sie die Währung',
'操作频繁' => 'Häufiger Betrieb',
'已清仓,请查看交易记录详情' => 'Das Lager wurde geräumt. Bitte überprüfen Sie die Transaktionsdaten',
'清仓失败' => 'Löschen fehlgeschlagen',
'请输入补仓数量' => 'Bitte geben Sie die Nachschub-Menge ein',
'交易币种不存在' => 'Die Transaktionswährung existiert nicht',
'请开启策略' => 'Bitte öffnen Sie die Politik',
'加仓成功' => 'Erweiterung des Lagers erfolgreich',
'请输入设置的补仓最低余额限制' => 'Bitte geben Sie die eingestellte Mindestbalance-Grenze für die Auffüllung ein',
];
+4
View File
@@ -0,0 +1,4 @@
<?php
return [
"系统繁忙" => "系统繁忙",
];
+30
View File
@@ -0,0 +1,30 @@
<?php
return [
'操作频繁' => 'Häufiger Betrieb',
'请输入邀请码' => 'Bitte geben Sie den Einladungscode ein',
'推荐码不存在' => 'Code der Empfehlung existiert nicht',
'创建钱包失败 请联系客服' => 'Das Erstellen der Brieftasche ist fehlgeschlagen, wenden Sie sich bitte an den Kundendienst',
'请输入正确的姓名' => 'Bitte geben Sie den richtigen Namen ein',
'请输入正确的身份证号' => 'Bitte geben Sie die richtige ID-Nummer ein',
'您已实名' => 'Du hast deinen richtigen Namen.',
'提交成功' => 'Eingereicht erfolgreich',
'系统繁忙' => 'System besetzt',
'请输入原始密码' => 'Bitte geben Sie das Originalpasswort ein',
'请选择修改的密码类型' => 'Bitte wählen Sie den Passworttyp aus, um ihn zu ändern',
'请输入新密码' => 'Bitte ein neues Passwort eingeben',
'原始密码错误' => 'Ursprünglicher Passwort-Fehler',
'新密码与旧密码相同,请重新输入' => 'Das neue Passwort ist dasselbe wie das alte Passwort, bitte erneut eingeben',
'请上传身份证正面照' => 'Bitte laden Sie das Foto Ihrer Personalausweise hoch',
'请上传身份证背面照' => 'Bitte laden Sie das Foto auf der Rückseite Ihres Personalausweises hoch',
'请输入账号密码' => 'Bitte geben Sie das Passwort ein',
'登录成功' => 'Login erfolgreich',
'注册成功' => 'Anmeldung erfolgreich',
'推出成功' => 'Erfolgreicher Start',
'请输入完整信息' => 'Bitte geben Sie vollständige Informationen ein',
'邮箱错误' => 'Fehler in der Mailbox',
'用户不存在' => 'Benutzer existiert nicht',
'验证码错误' => 'Fehler bei der Überprüfung',
'重置密码成功' => 'Passwort zurücksetzen erfolgreich',
];

Some files were not shown because too many files have changed in this diff Show More