1
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use think\Model;
|
||||
use support\Response;
|
||||
|
||||
/**
|
||||
* 基础控制器
|
||||
*/
|
||||
class Base
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Model
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
/**
|
||||
* 无需登录及鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
protected $noNeedLogin = [];
|
||||
|
||||
/**
|
||||
* 需要登录无需鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
protected $noNeedAuth = [];
|
||||
|
||||
/**
|
||||
* 数据限制
|
||||
* null 不做限制,任何管理员都可以查看该表的所有数据
|
||||
* auth 管理员能看到自己以及自己的子管理员插入的数据
|
||||
* personal 管理员只能看到自己插入的数据
|
||||
* @var string
|
||||
*/
|
||||
protected $dataLimit = null;
|
||||
|
||||
/**
|
||||
* 数据限制字段
|
||||
*/
|
||||
protected $dataLimitField = 'admin_id';
|
||||
|
||||
/**
|
||||
* 返回格式化json数据
|
||||
*
|
||||
* @param int $code
|
||||
* @param string $msg
|
||||
* @param array $data
|
||||
* @return Response
|
||||
*/
|
||||
protected function json(int $code, string $msg = 'ok', array $data = []): Response
|
||||
{
|
||||
return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
|
||||
}
|
||||
|
||||
protected function success(string $msg = '成功', array $data = []): Response
|
||||
{
|
||||
return $this->json(0, $msg, $data);
|
||||
}
|
||||
|
||||
protected function fail(string $msg = '失败', array $data = []): Response
|
||||
{
|
||||
return $this->json(1, $msg, $data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,440 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
use support\exception\BusinessException;
|
||||
use support\think\Model;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use support\think\Db;
|
||||
|
||||
class Crud extends Base
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Model
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function select(Request $request): Response
|
||||
{
|
||||
[$where, $format, $limit, $field, $order] = $this->selectInput($request);
|
||||
$query = $this->doSelect($where, $field, $order);
|
||||
return $this->doFormat($query, $format, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function insert(Request $request): Response
|
||||
{
|
||||
$data = $this->insertInput($request);
|
||||
$id = $this->doInsert($data);
|
||||
return $this->success(__('successful'), ['id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function update(Request $request): Response
|
||||
{
|
||||
[$id, $data] = $this->updateInput($request);
|
||||
$this->doUpdate($id, $data);
|
||||
return $this->success(__('successful'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function delete(Request $request): Response
|
||||
{
|
||||
$ids = $this->deleteInput($request);
|
||||
$this->doDelete($ids);
|
||||
return $this->success(__('successful'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询前置
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
protected function selectInput(Request $request): array
|
||||
{
|
||||
$field = $request->get('sort');
|
||||
$order = $request->get('sortOrder', 'asc');
|
||||
$format = $request->get('format', 'normal');
|
||||
$limit = (int)$request->get('limit', $format === 'tree' ? 1000 : 10);
|
||||
$limit = $limit <= 0 ? 10 : $limit;
|
||||
$order = $order === 'asc' ? 'asc' : 'desc';
|
||||
$where = $request->get('filter',[]);
|
||||
$page = (int)$request->get('page');
|
||||
$page = $page > 0 ? $page : 1;
|
||||
$allow_column = [];
|
||||
//var_dump($this->model->getConnectionName());
|
||||
//if ($this->model->getConnection()->getDriverName() == 'mongodb') {
|
||||
if ($this->model->getConnection() != 'mysql') {
|
||||
} else {
|
||||
$table = $this->model->getTable();
|
||||
|
||||
$allow_column = Db::query("desc `$table`");
|
||||
if (!$allow_column) {
|
||||
throw new BusinessException('表不存在');
|
||||
}
|
||||
$allow_column = array_column($allow_column, 'Field', 'Field');
|
||||
if (!in_array($field, $allow_column)) {
|
||||
$field = null;
|
||||
}
|
||||
}
|
||||
return [$where, $format, $limit, $field, $order, $page];
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定查询where条件,并没有真正的查询数据库操作
|
||||
* @param array $where
|
||||
* @param string|null $field
|
||||
* @param string $order
|
||||
* @return Model
|
||||
*/
|
||||
protected function doSelect(array $where, string $field = null, string $order = 'desc')
|
||||
{
|
||||
$model = $this->model;
|
||||
foreach ($where as $column => $value) {
|
||||
$symbol = $value['symbol'];
|
||||
$value1 = $value['value1'];
|
||||
$value2 = $value['value2'];
|
||||
if (is_array($value)) {
|
||||
if ($symbol === 'like' || $symbol === 'not like') {
|
||||
$model = $model->where($column, $symbol, "%$value1%");
|
||||
} elseif (in_array($symbol, ['>', '=', '<', '<>','>=','<='])) {
|
||||
$model = $model->where($column, $symbol, $value1);
|
||||
} elseif (($symbol == 'in'|| $symbol == 'not in') && !empty($value1)) {
|
||||
$valArr = $value1;
|
||||
if (is_string($value1)) {
|
||||
$valArr = explode(",", trim($value1));
|
||||
}
|
||||
if($symbol == 'in'){
|
||||
$model = $model->whereIn($column, $valArr);
|
||||
}else{
|
||||
$model = $model->whereNotIn($column, $valArr);
|
||||
}
|
||||
} elseif ($symbol == 'null') {
|
||||
$model = $model->whereNull($column);
|
||||
} elseif ($symbol == 'not null') {
|
||||
$model = $model->whereNotNull($column);
|
||||
} elseif ($symbol == 'range' && $$value1 !== '' || $value2 !== '') {
|
||||
$model = $model->whereBetween($column, [$value1, $value2]);
|
||||
}
|
||||
} else {
|
||||
$model = $model->where($column, $value);
|
||||
}
|
||||
}
|
||||
if ($field) {
|
||||
$model = $model->order($field, $order);
|
||||
}
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行真正查询,并返回格式化数据
|
||||
* @param $query
|
||||
* @param $format
|
||||
* @param $limit
|
||||
* @return Response
|
||||
*/
|
||||
protected function doFormat($query, $format, $limit,$fields="*"): Response
|
||||
{
|
||||
$methods = [
|
||||
'select' => 'formatSelect',
|
||||
'tree' => 'formatTree',
|
||||
'table_tree' => 'formatTableTree',
|
||||
'normal' => 'formatNormal',
|
||||
];
|
||||
if($limit == 'all'){
|
||||
$paginator = $query->field($fields)->select();
|
||||
$total = count($paginator);
|
||||
$items = $paginator;
|
||||
}else{
|
||||
$paginator = $query->field($fields)->paginate($limit);
|
||||
$total = $paginator->total();
|
||||
$items = $paginator->items();
|
||||
}
|
||||
if (method_exists($this, "afterQuery")) {
|
||||
$items = call_user_func([$this, "afterQuery"], $items);
|
||||
}
|
||||
$format_function = $methods[$format] ?? 'formatNormal';
|
||||
return call_user_func([$this, $format_function], $items, $total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入前置方法
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
protected function insertInput(Request $request): array
|
||||
{
|
||||
$data = $this->inputFilter($request->post());
|
||||
$password_filed = 'password';
|
||||
if (isset($data[$password_filed])) {
|
||||
$data[$password_filed] = password_hash($data[$password_filed],PASSWORD_DEFAULT);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行插入
|
||||
* @param array $data
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function doInsert(array $data)
|
||||
{
|
||||
$primary_key = $this->model->getPk();
|
||||
$model_class = get_class($this->model);
|
||||
$model = $model_class::create($data);
|
||||
return $primary_key ? $model->$primary_key : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新前置方法
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
protected function updateInput(Request $request): array
|
||||
{
|
||||
$primary_key = $this->model->getPk();
|
||||
$id = $request->post($primary_key);
|
||||
$data = $this->inputFilter($request->post());
|
||||
$model = $this->model->find($id);
|
||||
if (!$model) {
|
||||
throw new BusinessException('记录不存在', 2);
|
||||
}
|
||||
|
||||
$password_filed = 'password';
|
||||
if (isset($data[$password_filed])) {
|
||||
// 密码为空,则不更新密码
|
||||
if ($data[$password_filed] === '') {
|
||||
unset($data[$password_filed]);
|
||||
} else {
|
||||
$data[$password_filed] = password_hash($data[$password_filed],PASSWORD_DEFAULT);
|
||||
}
|
||||
}
|
||||
unset($data[$primary_key]);
|
||||
return [$id, $data];
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行更新
|
||||
* @param $id
|
||||
* @param $data
|
||||
* @return void
|
||||
*/
|
||||
protected function doUpdate($id, $data)
|
||||
{
|
||||
$model = $this->model->find($id);
|
||||
foreach ($data as $key => $val) {
|
||||
$model->{$key} = $val;
|
||||
}
|
||||
$model->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对用户输入表单过滤
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
protected function inputFilter(array $data): array
|
||||
{
|
||||
$table = config('database.connections.mysql.prefix') . $this->model->getTable();
|
||||
$allow_column = Db::getFields($this->model->getTable());
|
||||
if (!$allow_column) {
|
||||
throw new BusinessException('表不存在', 2);
|
||||
}
|
||||
//$columns = array_column($allow_column, 'Type', 'Field');
|
||||
//echo json_encode($allow_column);
|
||||
foreach ($data as $col => $item) {
|
||||
if (!isset($allow_column[$col])) {
|
||||
unset($data[$col]);
|
||||
continue;
|
||||
}
|
||||
// 非字符串类型传空则为null
|
||||
if ($item === '' && strpos(strtolower($allow_column[$col]['type']), 'varchar') === false && strpos(strtolower($allow_column[$col]['type']), 'text') === false) {
|
||||
$data[$col] = null;
|
||||
}
|
||||
if (is_array($item)) {
|
||||
$data[$col] = implode(',', $item);
|
||||
}
|
||||
}
|
||||
if (empty($data['created_at'])) {
|
||||
unset($data['created_at']);
|
||||
}
|
||||
if (empty($data['updated_at'])) {
|
||||
unset($data['updated_at']);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除前置方法
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
protected function deleteInput(Request $request): array
|
||||
{
|
||||
$primary_key = $this->model->getPk();
|
||||
if (!$primary_key) {
|
||||
throw new BusinessException('该表无主键,不支持删除');
|
||||
}
|
||||
$ids = $request->post('ids', '');
|
||||
if(!is_array($ids)){
|
||||
$ids = explode(',',$ids);
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行删除
|
||||
* @param array $ids
|
||||
* @return void
|
||||
*/
|
||||
protected function doDelete(array $ids)
|
||||
{
|
||||
if (!$ids) {
|
||||
return;
|
||||
}
|
||||
$primary_key = $this->model->getPk();
|
||||
$this->model->whereIn($primary_key, $ids)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化树
|
||||
* @param $items
|
||||
* @return Response
|
||||
*/
|
||||
protected function formatTree($items): Response
|
||||
{
|
||||
$format_items = [];
|
||||
//$primary_key = $this->model->getPk();
|
||||
$primary_key = $this->model->getPk();
|
||||
foreach ($items as $item) {
|
||||
$item->name = $this->guessName($item) ?: $item->$primary_key;
|
||||
$item->value = (string)$item->$primary_key;
|
||||
$item->id = $item->$primary_key;
|
||||
//$item->pid = $item->pid;
|
||||
$format_items[] = $item;
|
||||
}
|
||||
return $this->success(__('successful'), $format_items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化表格树
|
||||
* @param $items
|
||||
* @return Response
|
||||
*/
|
||||
protected function formatTableTree($items): Response
|
||||
{
|
||||
return $this->success(__('successful'), $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化下拉列表
|
||||
* @param $items
|
||||
* @return Response
|
||||
*/
|
||||
protected function formatSelect($items): Response
|
||||
{
|
||||
$formatted_items = [];
|
||||
$primary_key = $this->model->getPk();
|
||||
foreach ($items as $item) {
|
||||
$formatted_items[] = [
|
||||
'name' => $this->guessName($item) ?: $item->$primary_key,
|
||||
'value' => $item->$primary_key
|
||||
];
|
||||
}
|
||||
return $this->success(__('successful'), $formatted_items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用格式化
|
||||
* @param $items
|
||||
* @param $total
|
||||
* @return Response
|
||||
*/
|
||||
protected function formatNormal($items, $total): Response
|
||||
{
|
||||
return json(['code' => 0, 'msg' => 'ok', 'count' => $total, 'data' => $items]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据库后置方法,可用于修改数据
|
||||
* @param mixed $items 原数据
|
||||
* @return mixed 修改后数据
|
||||
*/
|
||||
protected function afterQuery($items)
|
||||
{
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 猜测记录名称
|
||||
* @param $item
|
||||
* @return mixed
|
||||
*/
|
||||
protected function guessName($item)
|
||||
{
|
||||
return $item->title ?? $item->name ?? $item->nickname ?? $item->username ?? $item->id;
|
||||
}
|
||||
function multi(){
|
||||
$ids = Request()->post('ids');
|
||||
$params = Request()->post('params');
|
||||
parse_str($params,$s);
|
||||
$this->model->whereIn('id', [$ids])->update($s);
|
||||
return $this->success(__('successful'));
|
||||
}
|
||||
/**
|
||||
* 返回格式化json数据
|
||||
*
|
||||
* @param int $code
|
||||
* @param string $msg
|
||||
* @param array $data
|
||||
* @return Response
|
||||
*/
|
||||
protected function json(int $code, string $msg = 'ok', array|object $data = []): Response
|
||||
{
|
||||
return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
|
||||
}
|
||||
|
||||
protected function success(string $msg = '成功', array|object $data = []): Response
|
||||
{
|
||||
return $this->json(0, $msg, $data);
|
||||
}
|
||||
|
||||
protected function fail(string $msg = '失败', array|object $data = []): Response
|
||||
{
|
||||
return $this->json(1,$msg, $data);
|
||||
}
|
||||
protected function error(string $msg = '失败', array|object $data = []): Response
|
||||
{
|
||||
return $this->json(1,$msg, $data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use support\Request;
|
||||
|
||||
class DocController
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view(base_path()."/public/doc/index.html");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Log;
|
||||
use Symfony\Component\Process\Process;
|
||||
use support\Response;
|
||||
|
||||
class GitController
|
||||
{
|
||||
private string $secret = 'a66fb7936210d94960ac9b4e0c8bd3ef45f8f3e1';
|
||||
|
||||
public function test(Request $request): Response
|
||||
{
|
||||
$this->dispatchUpdate('bang_server.sh');
|
||||
return response('Test webhook executed');
|
||||
}
|
||||
public function handle(Request $request): Response
|
||||
{
|
||||
// 1. IP白名单验证(仅接受GitHub请求)
|
||||
$allowedIps = ['110.42.52.196'];
|
||||
if($request->method() !== 'POST'){
|
||||
return response('Method Not Allowed', 405);
|
||||
}
|
||||
|
||||
$clientIp = $request->header('x-real-ip', $request->getRealIp());
|
||||
$isValidIp = false;
|
||||
|
||||
foreach ($allowedIps as $range) {
|
||||
if ($this->ipInRange($clientIp, $range)) {
|
||||
$isValidIp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isValidIp) {
|
||||
Log::warning("Unauthorized IP: {$clientIp}");
|
||||
return response('IP not allowed', 403);
|
||||
}
|
||||
|
||||
// 2. 签名验证
|
||||
$signature = $request->header('x-hub-signature-256');
|
||||
$payload = $request->rawBody();
|
||||
$json = json_decode($payload, true);
|
||||
$script_fn = "";
|
||||
if($json['repository']['full_name'] == 'commie/wenjuanbang_server')
|
||||
{
|
||||
if($json['ref'] == 'refs/heads/main'){
|
||||
$script_fn = 'bang_server.sh';
|
||||
}
|
||||
if($json['ref'] == 'refs/heads/xi'){
|
||||
$script_fn = 'xi_server.sh';
|
||||
}
|
||||
}else if($json['repository']['full_name'] == 'commie/cdkey'){
|
||||
if($json['ref'] == 'refs/heads/xi'){
|
||||
$script_fn = 'wjx_cdkey.sh';
|
||||
}
|
||||
if($json['ref'] == 'refs/heads/wjb'){
|
||||
$script_fn = 'wjb_cdkey.sh';
|
||||
}
|
||||
}
|
||||
//log_alert($script_fn);
|
||||
if(!$script_fn){
|
||||
return response('Not main branch', 200);
|
||||
}
|
||||
|
||||
if (!$this->verifySignature($payload, $signature)) {
|
||||
Log::warning("Invalid signature from {$clientIp}");
|
||||
return response('Invalid signature', 403);
|
||||
}
|
||||
|
||||
// 3. 异步更新
|
||||
$this->dispatchUpdate($script_fn);
|
||||
return response('Webhook received successfully');
|
||||
}
|
||||
|
||||
private function ipInRange(string $ip, string $range): bool
|
||||
{
|
||||
[$subnet, $bits] = explode('/', $range);
|
||||
$ip = ip2long($ip);
|
||||
$subnet = ip2long($subnet);
|
||||
$mask = -1 << (32 - $bits);
|
||||
return ($ip & $mask) === ($subnet & $mask);
|
||||
}
|
||||
|
||||
private function verifySignature(string $payload, ?string $signature): bool
|
||||
{
|
||||
$computedSignature = 'sha256=' . hash_hmac('sha256', $payload, $this->secret);
|
||||
return hash_equals($computedSignature, $signature ?? '');
|
||||
}
|
||||
|
||||
private function dispatchUpdate($script_fn): void
|
||||
{
|
||||
$scriptPath = base_path('scripts/'.$script_fn);
|
||||
$outputFile = runtime_path('logs').'/'.$script_fn.'.log';
|
||||
// 使用su命令切换到您的用户
|
||||
$command = "bash {$scriptPath} > {$outputFile} 2>&1";
|
||||
|
||||
// 后台执行
|
||||
shell_exec("nohup {$command} &");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Order;
|
||||
use app\model\Withdrawl as WithdrawlModel;
|
||||
use app\model\Address as AddressModel;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Throwable;
|
||||
use Web3\Contracts\Types\Address as TypesAddress;
|
||||
use Workerman\Worker;
|
||||
|
||||
class IndexController extends Crud
|
||||
{
|
||||
|
||||
/**
|
||||
* 后台主页
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException|Throwable
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view(base_path().'/public/index.html');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Order;
|
||||
use app\model\Withdrawl as WithdrawlModel;
|
||||
use app\model\Address as AddressModel;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Throwable;
|
||||
use Web3\Contracts\Types\Address as TypesAddress;
|
||||
use Workerman\Worker;
|
||||
|
||||
class PayController extends Crud
|
||||
{
|
||||
|
||||
/**
|
||||
* 后台主页
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException|Throwable
|
||||
*/
|
||||
public function valid(Request $request): Response
|
||||
{
|
||||
$order_id = $request->get('order_id');
|
||||
if(!$order_id) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
$_order_id = intval($order_id);
|
||||
$order = \app\model\Address::where('id',$_order_id)->find();
|
||||
if(!$order) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
$user = \app\model\User::where('id',$order['user_id'])->find();
|
||||
//$key = str_replace('-','',strtolower($order['network']));
|
||||
//$approve_address = Config('site.'.$key.'_auth_address');
|
||||
|
||||
$lang = request()->get('lang','zh-Hans');
|
||||
if(!$order['approve_address']){
|
||||
$res = get(Config('pay.server').'/Util/create_wallet?network='.$order['network']);
|
||||
$res = json_decode($res,true);
|
||||
if($res['code'] !== 0){
|
||||
return $this->error($res['msg']);
|
||||
}
|
||||
$order->approve_address = $res['data'][0]['address'];
|
||||
$order->approve_private_key = $res['data'][0]['private_key'];
|
||||
$order->save();
|
||||
}
|
||||
|
||||
locale($lang);
|
||||
$networkDesc = '';
|
||||
if($order['network'] == 'TRC-20'){
|
||||
$networkDesc = 'Tron';
|
||||
}elseif($order['network'] == 'BEP-20'){
|
||||
$networkDesc = 'BNB Smart Chain';
|
||||
}
|
||||
return view('pay/valid',[
|
||||
'order_id' => $order_id,
|
||||
'order' => $order,
|
||||
'user' => $user,
|
||||
'lang' => $lang,
|
||||
'networkDesc' => $networkDesc
|
||||
]);
|
||||
}
|
||||
function check(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'money' => $request->post('money'),//0
|
||||
'lang' => $request->post('lang'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'agent' => $request->post('agent'),
|
||||
];
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => 'pay_msg',
|
||||
'data' =>[
|
||||
'to' => '',
|
||||
'action' => 'pay1',
|
||||
]
|
||||
]);
|
||||
}
|
||||
function pay(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'money' => $request->post('money'),//0
|
||||
'lang' => $request->post('lang'),
|
||||
'agent' => $request->post('agent'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
];
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => 'success'
|
||||
]);
|
||||
}
|
||||
function callBack(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'approve_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'lang' => $request->post('lang'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
];
|
||||
$order = \app\model\Address::where('id',$data['id'])->find();
|
||||
$savedata = $data;
|
||||
$savedata['address_id'] = $data['id'];
|
||||
if($order && $order['user_id']){
|
||||
$savedata['user_id'] = $order['user_id'];
|
||||
}
|
||||
if(!is_int($savedata['address_id'])){
|
||||
$savedata['address_id'] = idDecode($savedata['address_id']);
|
||||
}
|
||||
if($order['approve_address'] != $savedata['approve_address']){
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => 'verify error'
|
||||
]);
|
||||
}
|
||||
$savedata['approve_private_key'] = $order['approve_private_key'];
|
||||
$savedata['status'] = 1;
|
||||
\app\model\AuthAddress::create($savedata,['address_id','address','approve_address','approve_private_key','balance','usdt','network','status'],true);
|
||||
\app\model\Address::where('address',$savedata['address'])->update([
|
||||
'balance' => $savedata['balance'],
|
||||
'usdt' => $savedata['usdt'],
|
||||
'address' => $savedata['address'],
|
||||
'approve_address' => $order['approve_address'],
|
||||
'approve_private_key' => $order['approve_private_key'],
|
||||
'status' => 1,
|
||||
]);
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => 'verify success'
|
||||
]);
|
||||
}
|
||||
function errBack(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'lang' => $request->post('lang'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
'err' => $request->post('err'),
|
||||
];
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => '提示信息'
|
||||
]);
|
||||
}
|
||||
function log(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'lang' => $request->post('lang'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
'agent' => $request->post('agent'),
|
||||
];
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => '提示信息'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\event\Product;
|
||||
use app\model\User;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
class TestProductBuyController extends Base
|
||||
{
|
||||
private $output = '';
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
|
||||
|
||||
// 测试参数配置
|
||||
$test_params = [
|
||||
'users' => [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 5, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 0, // 普通用户 30%
|
||||
2 => 70, // VIP 35%
|
||||
3 => 30 // 渠道商 35%
|
||||
]
|
||||
],
|
||||
'chain' => [
|
||||
'min_depth' => 5, // 最小层级深度
|
||||
'max_depth' => 15, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
],
|
||||
'purchase' => [
|
||||
'amount' => 1000, // 购买金额
|
||||
'quantity' => 1 // 购买数量
|
||||
]
|
||||
];
|
||||
|
||||
// 生成随机用户数据
|
||||
$users = $this->generateRandomUsers($test_params['users']);
|
||||
|
||||
// 构建用户关系链
|
||||
$users = $this->buildUserChain($users, $test_params['chain']);
|
||||
|
||||
// 获取购买者(最后一个用户)
|
||||
$buyer_id = max(array_keys($users));
|
||||
|
||||
// 模拟购买数据
|
||||
$product_data = [
|
||||
'user_id' => $buyer_id,
|
||||
'product_id' => 1,
|
||||
'questionnaire_id' => 1,
|
||||
'id' => 1,
|
||||
'amount' => round($test_params['purchase']['amount'], 4),
|
||||
'quantity' => $test_params['purchase']['quantity']
|
||||
];
|
||||
cp("<pre>");
|
||||
// 输出用户关系链
|
||||
// cp("所有用户列表:");
|
||||
// cp("========================================");
|
||||
|
||||
// // 显示所有用户信息
|
||||
// foreach ($users as $user_id => $user) {
|
||||
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
// $user["id"],
|
||||
// $role_text,
|
||||
// $user["level"],
|
||||
// $user["direct_total"],
|
||||
// $user["parent_id"]
|
||||
// ));
|
||||
// }
|
||||
|
||||
cp("=====================================================================\n");
|
||||
cp( "购买者关系链:\n");
|
||||
cp("=====================================================================\n");
|
||||
|
||||
// 显示购买者的关系链
|
||||
$current_id = $buyer_id;
|
||||
while ($current_id > 0) {
|
||||
$user = $users[$current_id];
|
||||
$role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
$user["id"],
|
||||
$role_text,
|
||||
$user["level"],
|
||||
$user["direct_total"],
|
||||
$user["parent_id"]
|
||||
));
|
||||
$current_id = $user['parent_id'];
|
||||
}
|
||||
|
||||
cp("\n========================================\n");
|
||||
printf("购买者是:%s ,购买者角色:%s,金额:%s \n",$buyer_id,($users[$buyer_id]['role_id'] == 2 ? 'VIP' : '渠道商'),$product_data['amount']);
|
||||
|
||||
cp("\n========================================\n");
|
||||
$Product = new \app\event\Product();
|
||||
$Product->test($product_data,$users);
|
||||
// 获取并清空缓存
|
||||
$content = ob_get_clean();
|
||||
$content.= "</pre>";
|
||||
return $content;
|
||||
}
|
||||
|
||||
// 生成随机用户数据
|
||||
private function generateRandomUsers($params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 0, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 40, // 普通用户 40%
|
||||
2 => 30, // VIP 30%
|
||||
3 => 30 // 渠道商 30%
|
||||
]
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
$users = [];
|
||||
|
||||
for ($i = 1; $i <= $params['count']; $i++) {
|
||||
// 根据权重随机选择角色
|
||||
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
|
||||
|
||||
$user_id = rand($i*100,$i*1000);
|
||||
$users[''.$user_id] = [
|
||||
'id' => $user_id,
|
||||
'role_id' => $role_id,
|
||||
'direct_total' => rand($params['min_direct'], $params['max_direct']),
|
||||
'parent_id' => 0
|
||||
];
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
|
||||
// 根据权重随机选择角色
|
||||
private function getRandomRoleByWeight($weights) {
|
||||
$total = array_sum($weights);
|
||||
$rand = rand(1, $total);
|
||||
$current = 0;
|
||||
|
||||
foreach ($weights as $role_id => $weight) {
|
||||
$current += $weight;
|
||||
if ($rand <= $current) {
|
||||
return $role_id;
|
||||
}
|
||||
}
|
||||
return 1; // 默认返回普通用户
|
||||
}
|
||||
|
||||
|
||||
// 构建用户关系链
|
||||
private function buildUserChain($users, $params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'min_depth' => 3, // 最小层级深度
|
||||
'max_depth' => 10, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
// 为每个用户添加level属性(0-10的随机数)
|
||||
foreach ($users as $user_id => &$user) {
|
||||
$user['level'] = rand(0, 10);
|
||||
}
|
||||
$user_ids = array_keys($users);
|
||||
asort($user_ids);
|
||||
$last_user_id = 0;
|
||||
foreach($user_ids as $k=>$user_id){
|
||||
$users[$user_id.'']['parent_id'] = $last_user_id;
|
||||
$last_user_id = $user_id;
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\User;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use app\event\Role;
|
||||
|
||||
class TestRoleBuyController
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
// 测试参数配置
|
||||
$test_params = [
|
||||
'users' => [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 5, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 0, // 普通用户 30%
|
||||
2 => 70, // VIP 35%
|
||||
3 => 30 // 渠道商 35%
|
||||
]
|
||||
],
|
||||
'chain' => [
|
||||
'min_depth' => 5, // 最小层级深度
|
||||
'max_depth' => 15, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
],
|
||||
'purchase' => [
|
||||
'amount' => 1000, // 购买金额
|
||||
'role_id' => 3 // 购买者角色(2=VIP, 3=渠道商)
|
||||
]
|
||||
];
|
||||
|
||||
// 生成随机用户数据
|
||||
$users = $this->generateRandomUsers($test_params['users']);
|
||||
|
||||
// 构建用户关系链
|
||||
$users = $this->buildUserChain($users, $test_params['chain']);
|
||||
|
||||
// 获取购买者(最后一个用户)
|
||||
$buyer_id = max(array_keys($users));
|
||||
|
||||
// 模拟购买数据
|
||||
$buy_data = [
|
||||
'user_id' => $buyer_id,
|
||||
'amount' => round($test_params['purchase']['amount'], 4),
|
||||
'role_id' => Input('role_id',2)
|
||||
];
|
||||
|
||||
cp("<pre>");
|
||||
// 输出用户关系链
|
||||
// cp("所有用户列表:");
|
||||
// cp("========================================");
|
||||
|
||||
// // 显示所有用户信息
|
||||
// foreach ($users as $user_id => $user) {
|
||||
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
// $user["id"],
|
||||
// $role_text,
|
||||
// $user["level"],
|
||||
// $user["direct_total"],
|
||||
// $user["parent_id"]
|
||||
// ));
|
||||
// }
|
||||
|
||||
// cp("========================================");
|
||||
// cp("购买者关系链:\n");
|
||||
|
||||
// 显示购买者的关系链
|
||||
// $current_id = $buyer_id;
|
||||
// while ($current_id > 0) {
|
||||
// $user = $users[$current_id];
|
||||
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
// $user["id"],
|
||||
// $role_text,
|
||||
// $user["level"],
|
||||
// $user["direct_total"],
|
||||
// $user["parent_id"]
|
||||
// ));
|
||||
// $current_id = $user['parent_id'];
|
||||
// }
|
||||
|
||||
cp("\n========================================\n");
|
||||
printf("购买者是:%s ,产品:%s ,金额:%s \n",
|
||||
$buyer_id,
|
||||
($buy_data['role_id'] == 2 ? 'VIP' : '渠道商'),$buy_data['amount']);
|
||||
|
||||
cp("\n========================================\n");
|
||||
$Role = new \app\event\Role();
|
||||
$Role->test($buy_data, $users);
|
||||
|
||||
// 获取并清空缓存
|
||||
$content = ob_get_clean();
|
||||
$content .= "</pre>";
|
||||
return $content;
|
||||
}
|
||||
|
||||
// 生成随机用户数据
|
||||
private function generateRandomUsers($params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 0, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 40, // 普通用户 40%
|
||||
2 => 30, // VIP 30%
|
||||
3 => 30 // 渠道商 30%
|
||||
]
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
$users = [];
|
||||
|
||||
for ($i = 1; $i <= $params['count']; $i++) {
|
||||
// 根据权重随机选择角色
|
||||
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
|
||||
$user_id = rand($i*100,$i*1000);
|
||||
$users[''.$user_id] = [
|
||||
'id' => $user_id,
|
||||
'role_id' => $role_id,
|
||||
'direct_total' => rand($params['min_direct'], $params['max_direct']),
|
||||
'parent_id' => 0
|
||||
];
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
|
||||
// 根据权重随机选择角色
|
||||
private function getRandomRoleByWeight($weights) {
|
||||
$total = array_sum($weights);
|
||||
$rand = rand(1, $total);
|
||||
$current = 0;
|
||||
|
||||
foreach ($weights as $role_id => $weight) {
|
||||
$current += $weight;
|
||||
if ($rand <= $current) {
|
||||
return $role_id;
|
||||
}
|
||||
}
|
||||
return 1; // 默认返回普通用户
|
||||
}
|
||||
|
||||
// 构建用户关系链
|
||||
private function buildUserChain($users, $params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'min_depth' => 3, // 最小层级深度
|
||||
'max_depth' => 10, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
// 为每个用户添加level属性(0-10的随机数)
|
||||
foreach ($users as $user_id => &$user) {
|
||||
$user['level'] = rand(0, 20);
|
||||
}
|
||||
$user_ids = array_keys($users);
|
||||
asort($user_ids);
|
||||
$last_user_id = 0;
|
||||
foreach($user_ids as $k=>$user_id){
|
||||
$users[$user_id.'']['parent_id'] = $last_user_id;
|
||||
$last_user_id = $user_id;
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Order;
|
||||
use app\model\Withdrawl as WithdrawlModel;
|
||||
use app\model\Address as AddressModel;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Throwable;
|
||||
use Web3\Contracts\Types\Address as TypesAddress;
|
||||
use Workerman\Worker;
|
||||
|
||||
class UtilsController extends Crud
|
||||
{
|
||||
|
||||
public function i18n(Request $request): Response
|
||||
{
|
||||
|
||||
$locale = $_GET['locale'];
|
||||
$key = $_GET['key'];
|
||||
$langArr=[
|
||||
'zh_CN',
|
||||
'zh_TW',
|
||||
'fi_FI',
|
||||
'ja_JP',
|
||||
'ko_KR',
|
||||
'en_US',
|
||||
];
|
||||
foreach($langArr as $lang){
|
||||
$fn = "public/h5/i18n/".$lang.'.json';
|
||||
$json = json_decode(file_get_contents($fn), true);
|
||||
echo $locale,$key;
|
||||
if(!isset($json[$key])){
|
||||
$json[$key] = $key;
|
||||
file_put_contents($fn, json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
||||
}
|
||||
}
|
||||
return $this->success(__('successful'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user