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
+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