HEX
Server: nginx/1.28.1
System: Linux 10-41-63-61 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64
User: www (1001)
PHP: 7.4.33
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/my.esfyn.top/Modules/Api/Http/Controllers/ApiController.php
<?php

namespace Modules\Api\Http\Controllers;

use App\Http\Controllers\MyController;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Modules\Api\Models\ApiModel;

class ApiController extends MyController
{
    protected $error = '返回失败';
    /**
     * @var string
     */
    protected $success = '返回成功';

    private $requestParams;


    /**
     * 无头CMS 接口入口
     * @return \Illuminate\Http\JsonResponse
     */
    public function entry()
    {
        $path = request()->input('path');
        $method = request()->method();
        $api = ApiModel::where('path', $path)->where('method', $method)->first();

        if (empty($api)) {
            return $this->error(['msg' => '非法接口']);
        }

        $this->requestParams = $this->validateParams($api->params);
        if (!is_array($this->requestParams)) {
            return $this->requestParams;
        }

        $api->use_count += 1;
        $api->save();

        return $this->{$api->source_type . "Action"}($api);
    }


    /**
     * 读取数据表
     * @param $api
     * @return \Illuminate\Http\JsonResponse
     */
    private function tableAction($api)
    {
        $limit = request()->input('limit', 15);

        $api->fields = json_decode($api->fields, true);
        $api->rel_table = json_decode($api->rel_table, true);
        $fields = $api->fields ?: ['*'];

        $query = DB::table($api->table_name)->where(function ($query) use ($api) {
            $requestParams = json_decode($api->params, true);
            $requestParams = array_column($requestParams, null, 'name');
            foreach ($this->requestParams as $key => $value) {
                if (!isset($requestParams[$key]['filter_type']) || $requestParams[$key]['filter_type'] == '=') {
                    $query->where($api->table_name . "." . $key, $value);
                } else {
                    $query->where($api->table_name . "." . $key, 'like', "%$value%");
                }
            }
        });

        if ($api->rel_table) {
            $api->rel_table = array_filter($api->rel_table);
            if ($api->fields) {
                $fields = array_map(function ($item) use ($api) {
                    return "{$api->table_name}.{$item}";
                }, $fields);
            }
            foreach ($api->rel_table as $f => $rel) {
                if (strstr($rel, ":") === false) {
                    $query->join($rel, $api->table_name . ".{$f}", "=", "{$rel}.id");
                    if ($api->fields) {
                        $fields[] = "{$rel}.*";
                    }
                } else {
                    [$table, $relFields] = explode(":", $rel);
                    $query->join($table, $api->table_name . ".{$f}", "=", "{$table}.id");
                    if ($api->fields) {
                        $array = explode(",", $relFields);
                        foreach ($array as $rf) {
                            $fields[] = "{$table}.{$rf}";
                        }
                    }
                }
            }
        }

        if (function_exists(Str::camel($api->table_name) . "Scope")) {
            $query = call_user_func_array(Str::camel($api->table_name) . "Scope", [$query, $api->table_name]);
        }

        $query->select($fields);

        if ($order = json_decode($api->order_field, true)) {
            $order = array_filter($order);
            foreach ($order as $field => $sort) {
                $query->orderBy($field, $sort);
            }
        }

        if ($api->return_type == 'object') {
            $result = $query->first();
            if ($result && $api->count_field) {
                $view = $result->{$api->count_field} + 1;
                DB::table($api->table_name)->where('id', $result->id)->update([$api->count_field => $view]);
            }
        } else {
            $result = $query->paginate($limit);
        }

        return $this->success(['data' => $result]);
    }


    /**
     * 转发请求
     * @param $api
     * @return \Illuminate\Http\JsonResponse
     * @throws GuzzleException
     */
    private function requestAction($api)
    {
        $url = $api->request_url;
        $option = [];

        if ($api->method == 'GET') {
            if (strstr($url, "?") !== false) {
                $url .= "&" . http_build_query($this->requestParams);
            } else {
                $url .= "?" . http_build_query($this->requestParams);
            }
        } else {
            $option['form_params'] = $this->requestParams;
        }

        $client = new Client();
        $response = $client->request($api->method, $url, $option);
        $content = $response->getBody()->getContents();

        $result = json_decode($content, true);
        return $this->success($result);
    }


    /**
     * 固定返回内容
     * @param $api
     * @return \Illuminate\Http\JsonResponse
     */
    private function contentAction($api): \Illuminate\Http\JsonResponse
    {
        $response = [];
        $array = json_decode($api->response, true);
        foreach ($array as $value) {
            if (isset($response[$value['name']]) && !is_array($response[$value['name']]) && $response[$value['name']]) {
                $response[$value['name']] = [
                    $response[$value['name']],
                    $value['value']
                ];
            } elseif (isset($response[$value['name']]) && is_array($response[$value['name']])) {
                $response[$value['name']][] = $value['value'];
            } else {
                $response[$value['name']] = $value['value'];
            }

        }
        return $this->success(['data' => $response]);
    }


    /**
     * @throws Exception
     */
    private function diyAction($api): \Illuminate\Http\JsonResponse
    {
        $handle = str_replace(".php", "", $api->handle);
        $handle = str_replace("/", "\\", $handle);

        $object = app()->make($handle);
        $result = $object->handle($this->requestParams);

        if (is_array($result)) {
            return $this->success($result);
        }

        return $result;
    }


    /**
     * 验证参数
     * @param $params
     * @return array|\Illuminate\Http\JsonResponse
     */
    private function validateParams($params)
    {
        $requestParams = [];
        $params = json_decode($params, true);
        foreach ($params as $param) {
            $input = $this->param($param['name'], '', $param['default']);
            if ($input === '' && $param['required']) {
                return $this->error(['msg' => ($param['remark'] ?: $param['name']) . '参数缺失']);
            } elseif ($input !== '') {
                $requestParams[$param['name']] = $input;
            }
        }

        return $requestParams;
    }


    /**
     * 过滤对象需要的字段
     * @param $data
     * @param $fields
     * @param $reject
     * @return array
     */
    public function objectFilterField($data, $fields = [], $reject = false): array
    {
        $values = [];
        $array = $data && !is_array($data) ? $data->toArray() : ($data ?: []);

        array_map(function ($item, $key) use ($fields, $reject, &$values) {

            if (
                ($reject === false && in_array($key, $fields)) ||
                ($reject === true && !in_array($key, $fields))
            ) {
                $values[$key] = is_null($item) ? '' : $item;
            }

        }, $array, array_keys($array));

        return $values;
    }

    /**
     * 过滤集合需要的字段
     * @param $data
     * @param array $fields
     * @param bool $reject
     * @return array
     */
    public function collectFilterField($data, $fields = [], $reject = false): array
    {
        $values = [];

        foreach ($data as $value) {

            $tmp = [];
            $array = !is_array($value) ? $value->toArray() : $value;

            foreach ($array as $key => $item) {
                if (
                    ($reject === false && in_array($key, $fields)) ||
                    ($reject === true && !in_array($key, $fields))
                ) {
                    $tmp[$key] = is_null($item) ? '' : $item;
                }
            }

            $values[] = $tmp;
        }

        return $values;
    }

    /**
     * 获取分页字段
     * @param $object
     * @return array
     */
    public function pageFilterField($object): array
    {
        return [
            'total' => $object->total(),
            'last_page' => $object->lastPage(),
            'current_page' => $object->currentPage(),
            'per_page' => $object->perPage()
        ];
    }


    /**
     * 获取用户ID
     * @return array|mixed|string|string[]|null
     */
    public function getUserId()
    {
        return $this->param('uid', 'intval');
    }

}