| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890 | <?phpnamespace App\Services\Interface;use App\Rules\EsExistsRule;use App\Rules\EsUniqueRule;use App\Services\Login\LoginTokenService;use GuzzleHttp\Client;use Illuminate\Http\JsonResponse;use Illuminate\Support\Arr;use Illuminate\Support\Facades\DB;use Illuminate\Support\Facades\Request;use Illuminate\Support\Facades\Validator;use Illuminate\Support\Str;use App\Services\Interface\Database\DbManager;class InterfaceService{    protected string $interfaceAlias;    protected array $websiteInfo;    protected int $websiteId;    protected array $interfaceInfo;    protected array $interfaceSettingInfo = [];    protected array $conditionSettingsInfo = [];    protected array $interfaceResultInfo = [];    protected array $assembleInfo = [];    protected ?array $assembleColumns = [];    protected array $columnIdToCodes = [];    protected string $table = '';    protected array $requestData = [];    protected ?array $execResultArr = [];    protected $tokenInfo;    protected int $userId;    /**     * InterfaceService constructor.     *     * @throws \Exception     */    public function __construct(string $interfaceAlias, array $websiteInfo)    {        if (empty($websiteInfo)) {            abort(508, '管理后台配置错误,站点不存在!');        }        $this->interfaceAlias = $interfaceAlias;        $this->websiteInfo = $websiteInfo;        $this->websiteId = $this->websiteInfo['id'];        // 获取接口信息        $interfaceInfo = DB::table('dep_interface')->where('is_use', 1)->where('is_delete', 0)->where('website_id', $this->websiteId)->where('en_alias', $this->interfaceAlias)->first();        if ($interfaceInfo) {            $this->interfaceInfo = get_object_vars($interfaceInfo);            // 请求参数配置            $this->interfaceSettingInfo = $this->interfaceInfo['request_settings'] ? json_decode($this->interfaceInfo['request_settings'], true) : [];            // 条件配置            $this->conditionSettingsInfo = $this->interfaceInfo['condition_settings'] ? json_decode($this->interfaceInfo['condition_settings'], true) : [];            // 请求结果配置            $this->interfaceResultInfo = $this->interfaceInfo['result_settings'] ? json_decode($this->interfaceInfo['result_settings'], true) : [];            // 系统接口使用            if (1 == $this->interfaceInfo['category_type']) {                $this->getAssembleInfo();                $this->getAssembleColumn();            }        } else {            abort(404, '接口不存在,请联系管理人员!');        }    }    /**     * 验证数据,如果有错误,则返回错误信息.     */    public function validator(): ?string    {        // 判断是否需要登录        if (isset($this->interfaceInfo['is_login']) && $this->interfaceInfo['is_login']) {            if (!$this->isLogin()) {                return '对不起,请先登录!';            }        }        // 如果没有配置参数,则默认验证成功        if (empty($this->interfaceSettingInfo)) {            return null;        }        $validatorAttributes = [];        $ruleArr = [];        // 设置的参数都要全部循环一遍,因为可能会设置固定参数,这样即使不传入参数,也可以使用        foreach ($this->interfaceSettingInfo as $item) {            $columnType = $item['column_type'] ?? 'input'; // 获取参数方式 Input Header Cookies Session File userId            $columnType = strtolower($columnType);            $column = $item['column'];            $tableColumn = $item['true_column'] ?? ''; // 真实使用的表字段            $ruleArr[$tableColumn ?: $column] = $item['rules'];            if ($item['is_fixed']) { // 固定值                $requestValue = trim($item['default']);            } else {                // 如果设置is_delete,则必须为固定值,防止被非法使用                if ('is_delete' == $column) {                    return '请求参数【' . $item['title'] . '(' . $item['column'] . ')】必须是固定值,不允许动态设置!!';                }                // 获取请求的参数                if ('input' == $columnType) {                    $requestValue = Request::input($column, $item['default']);                } elseif ('header' == $columnType) {                    $requestValue = Request::header($column, $item['default']);                } elseif ('cookies' == $columnType) {                    $requestValue = Request::cookie($column, $item['default']);                } elseif ('session' == $columnType) {                    $requestValue = Request::session()->get($column, $item['default']);                } elseif ('file' == $columnType) {                    $requestValue = Request::file($column, $item['default']);                } elseif ('userid' == $columnType) {                    // 必须登录才能获取用户信息                    if (!$this->isLogin()) {                        return '对不起,请先登录!';                    }                    $requestValue = $this->userId;                } else {                    $requestValue = Request::input($column, $item['default']);                }            }            $this->requestData[$tableColumn ?: $column] = $requestValue;            $validatorAttributes[$tableColumn ?: $column] = $item['title'];            // 使用函数            if (isset($item['type']) && $item['type'] && isset($item['conditions']) && $item['conditions']) {                $allData = array_merge($this->requestData, ['interfaceInfo' => $this->interfaceInfo], ['websiteInfo' => $this->websiteInfo]);                $this->execResult($item['conditions'], $allData);                // 如果有执行失败的返回错误                foreach ($this->execResultArr as $exeItem) {                    // 1 错误继续 2 错误退出 3 直接退出                    $back_type = $exeItem['back_type'];                    if (2 == $back_type) {                        if ($exeItem['error']) {                            return $exeItem['result']['msg'] ?? "系统错误";                        }                    } elseif ($back_type == 3) {                        return $exeItem['result'];                    }                }                // 处理参数返回的结果                if ($backR = $this->exeRequestManage($item, $tableColumn ?: $column)) {                    return $backR;                }            }        }        // 如果没有设置is_delete,默认设置0,只获取没有被删除的数据        if (!isset($this->requestData['is_delete'])) {            $this->requestData['is_delete'] = 0;        }        // 获取请求的参数的验证规则        list($validatorRules, $validatorMsgArr) = $this->getRequestRules($ruleArr);        $validator = Validator::make($this->requestData, $validatorRules, $validatorMsgArr, $validatorAttributes);        if ($validator->fails()) {            return $validator->errors()->first();        } else {            return null;        }    }    // 处理参数返回的结果    private function exeRequestManage($item, $column)    {        // 获取返回的结果设置        if (empty($item['return_settings']['resultIndexes'])) {            return '';        }        $return_settings = $item['return_settings'];        $resultIndexes = $return_settings['resultIndexes'];        if (empty($resultIndexes)) {            return '请求参数【' . $item['title'] . '(' . $item['column'] . ')】设置错误! - 请进入管理后台,重新设置!';        }        if (count($resultIndexes) > 1) {            $exeData = [];            foreach ($resultIndexes as $indexes) {                // 允许设置请求别名                $paramArr = explode(':', $indexes);                $index = $paramArr[0];                $indexAlias = $paramArr[1] ?? ''; // 别名                if ($indexAlias) {                    $exeData[$indexAlias] = Arr::get($this->requestData, $index);                } else {                    $exeData[] = Arr::get($this->requestData, $index);                }            }            $this->requestData[$column] = $exeData;        } else {            // 允许设置请求别名            $paramArr = explode(':', $resultIndexes[0]);            $index = $paramArr[0];            $this->requestData[$column] = Arr::get($this->requestData, $index);        }    }    /**     * 获取请求的参数的验证规则.     *     * @return array     */    private function getRequestRules(array $ruleArr)    {        $validatorRules = [];        $validatorMsgArr = [];        foreach ($ruleArr as $column => $rules) {            $typeArr = [];            foreach ($rules as $ruleValue) {                if (isset($ruleValue['type']) && 2 === $ruleValue['type']) { // 自定义规则                    $typeArr[] = $this->getRuleClass($ruleValue);                } else { // laravel验证规则                    if (isset($ruleValue['params']) && ($ruleValue['params'] || $ruleValue['params'] == 0)) {                        $typeArr[] = $ruleValue['rule'] . ':' . $ruleValue['params'];                    } else {                        $typeArr[] = $ruleValue['rule'];                    }                    if (!empty($ruleValue['error_msg'])) {                        $validatorMsgArr[$column . '.' . $ruleValue['rule']] = $ruleValue['error_msg'];                    }                }            }            $validatorRules[$column] = implode('|', $typeArr);        }        return [$validatorRules, $validatorMsgArr];    }    /**     * 判断是否已经登录.     */    public function isLogin(): bool    {        $loginToken = new LoginTokenService($this->websiteInfo['token_table']);        $this->tokenInfo = $loginToken->checkLogin();        if ($this->tokenInfo) {            $this->userId = $this->tokenInfo->user_id;            return true;        } else {            return false;        }    }    /**     * 获取当前接口信息.     *     * @return array     */    public function getInterfaceInfo(): array    {        return $this->interfaceInfo;    }    /**     * 获取请求的数据.     */    public function getRequestData(string $key = ''): array|string    {        if ($key) {            return $this->requestData[$key] ?? '';        }        return $this->requestData;    }    /**     * 设置请求的参数 可以对请求参数进行修改.     *     * @return $this     */    public function setRequestData(array $data): self    {        Request::merge($data);        return $this;    }    /**     * 获取集合(表)信息.     */    public function getAssembleInfo(): void    {        $assembleInfo = DB::table('sys_assemble')->find($this->interfaceInfo['assemble_id']);        $this->assembleInfo = get_object_vars($assembleInfo);        $this->table = $this->assembleInfo['schema'];    }    /**     * 获取表对应的字段列表,支持扩展表.     *     * @return void     */    public function getAssembleColumn(): void    {        $assembleInfo = DB::table('sys_assemble_column')->where('assemble_id', $this->interfaceInfo['assemble_id'])->where('is_delete', 0)->get();        $this->assembleColumns = array_map('get_object_vars', $assembleInfo->toArray());        // id 和 字段 组成的数组        $idArr = array_column($this->assembleColumns, 'id');        $codeArr = array_column($this->assembleColumns, 'code');        $this->columnIdToCodes = array_combine($idArr, $codeArr);    }    /**     * @throws \Exception     */    public function exec(): JsonResponse|null    {        if (1 == $this->interfaceInfo['category_type']) {            return $this->interfaceSysExec();        } else {            return $this->interfaceCustomExec();        }    }    /**     * 系统接口.     *     * @throws \Exception     */    public function interfaceSysExec(): JsonResponse    {        $manager = new DbManager($this->interfaceInfo, $this->assembleInfo, $this->assembleColumns, $this->requestData, $this->columnIdToCodes);        return $this->manageResult($manager->exec());    }    // 混合接口    public function interfaceCustomExec(): JsonResponse|null    {        $conditionsArr = $this->interfaceInfo['conditions'];        if ($conditionsArr) {            $allData = $this->requestData;            $this->execResult($conditionsArr, $allData);            // 如果有执行失败的返回错误            foreach ($this->execResultArr as $exeItem) {                // 1 错误继续 2 错误退出 3 直接退出                $back_type = $exeItem['back_type'];                if (2 == $back_type) {                    if ($exeItem['error']) {                        return responseMessage($exeItem['result']['code'], $exeItem['result']['msg'] ?? "系统错误");                    }                } elseif ($back_type == 3) {                    return responseMessage($exeItem['result']['code'], $exeItem['result']['msg'] ?? "系统错误", $exeItem['result']);                }            }            // 处理参数返回的结果            if ($backR = $this->exeRequestManage($exeItem, 'backRe')) {                return responseMessage(3001, $backR);            }        }        // 如果设置了返回值,则使用返回值        if ($this->requestData['backRe']) {            $result = $this->requestData['backRe'];            return responseMessage(1001, '', $result);        } else {            return null;        }    }    /**     * 结果集,操作并返回.     */    public function manageResult(mixed $result): JsonResponse    {        if ($result instanceof JsonResponse) {            return $result;        }        $resultInfo = $this->interfaceResultInfo;        if (empty($resultInfo)) {            return responseMessage(1001, '恭喜你,操作成功!', $result);        }        $operateType = $this->interfaceInfo['operate_type'];        if (1 === $operateType) {            // 关联查询            if ($resultInfo['is_use_relate'] && $resultInfo['relate_interfaces']) {                foreach ($resultInfo['relate_interfaces'] as $relate) {                    $search_type = $this->interfaceInfo['search_type'];                    if (1 === $search_type) { // 单条信息查询                        $result = $this->getChildrenInterfaceResult($result, $relate);                    } elseif (2 === $search_type) { // 分页查询                        foreach ($result['list'] as $key => $row) {                            $row = is_array($row) ? $row : get_object_vars($row);                            $result['list'][$key] = $this->getChildrenInterfaceResult($row, $relate);                        }                    } elseif (3 === $search_type) { // 列表                        foreach ($result as $key => $row) {                            $row = is_array($row) ? $row : get_object_vars($row);                            $result[$key] = $this->getChildrenInterfaceResult($row, $relate);                        }                    }                }            }        }        if ($result || 0 === $result || [] === $result) {            // 成功的操作            if (2 == $resultInfo['success']['type']) { // 有操作                $conditionsArr = $resultInfo['success']['conditions'];                $allData = array_merge($this->requestData, ['&result' => $result]);                if ($conditionsArr) {                    $this->execResult($conditionsArr, $allData);                    // 如果有执行失败的返回错误                    foreach ($this->execResultArr as $exeItem) {                        // 1 错误继续 2 错误退出 3 直接退出                        $back_type = $exeItem['back_type'];                        if (2 == $back_type) {                            if ($exeItem['error']) {                                return responseMessage($exeItem['result']['code'], $exeItem['result']['msg'] ?? "系统错误");                            }                        } elseif ($back_type == 3) {                            return responseMessage($exeItem['result']['code'], $exeItem['result']['msg'] ?? "系统错误", $exeItem['result']['result']);                        }                    }                    // 处理参数返回的结果                    if ($backR = $this->exeRequestManage($resultInfo['success'], 'backRe')) {                        return responseMessage(3001, $backR);                    }                }            }            /*             * 如果查询详情,直接返回字段值             * 为了方便设置参数的时候,可以直接使用返回值             */            if (1 == $operateType && 1 == $this->interfaceInfo['search_type']) {                if (isset($resultInfo['column_only_one']) && $resultInfo['column_only_one']) {                    $column_id = $resultInfo['columns'];                    $columnName = $this->columnIdToCodes[$column_id];                    $result = $result[$columnName] ?? null;                }            }            // 如果设置了返回值,则使用返回值,  不能判断返回值是否为空            $result = $this->requestData['backRe'] ?? $result;            return responseMessage(1001, $resultInfo['success']['msg'], $result);        } else {            // 失败的操作            if (2 == $resultInfo['failed']['type']) { // 有操作                $conditionsArr = $resultInfo['failed']['conditions'];                $allData = array_merge($this->requestData, ['&result' => $result]);                if ($conditionsArr) {                    $this->execResult($conditionsArr, $allData);                    // 如果有执行失败的返回错误                    foreach ($this->execResultArr as $exeItem) {                        // 1 错误继续 2 错误退出 3 直接退出                        $back_type = $exeItem['back_type'];                        if (2 == $back_type) {                            if ($exeItem['error']) {                                return responseMessage($exeItem['result']['code'], $exeItem['result']['msg'] ?? "系统错误");                            }                        } elseif ($back_type == 3) {                            return responseMessage($exeItem['result']['code'], $exeItem['result']['msg'] ?? "系统错误", $exeItem['result']['result']);                        }                    }                    // 处理参数返回的结果                    if ($backR = $this->exeRequestManage($resultInfo['failed'], 'backReFailed')) {                        return responseMessage(3001, $backR);                    }                }            }            return responseMessage(2001, $resultInfo['failed']['msg'], $this->requestData['backReFailed'] ?? '');        }    }    /**     * @param array $conditionsArr     * @param array $allData     * @return void     * @throws \GuzzleHttp\Exception\GuzzleException     */    private function execResult(array $conditionsArr, array $allData)    {        foreach ($conditionsArr as $item) {            if (1 == $item['type']) { // 内容处理                $expressionResult = $this->execManageCon($allData, $item);                $flag_uuid = $expressionResult['flag_uuid'] ?? '';                $this->execResultArr[$flag_uuid] = $expressionResult;                $this->requestData[$flag_uuid] = $expressionResult['result']['result'] ?? []; // 返回的的是 backJson() [error=>0,code=>0,result=>[]]                // 1 错误继续 2 错误退出 3 直接退出                $back_type = $expressionResult['back_type'];                if (2 == $back_type) {                    if ($expressionResult['error']) {                        break;                    }                } elseif ($back_type == 3) {                    break;                }            } elseif (2 == $item['type']) { // 判断条件                $this->checkExpression('result_type', $allData, $item['condition']);            }        }    }    // ######################################################################    /**     * 执行参数,判断参数的真假.     *     * @param string $searchOrResultType 判断是搜索内容处理,还是结果集内容管理     *     * @throws \GuzzleHttp\Exception\GuzzleException     */    private function checkExpression(string $searchOrResultType, array $data, array $condition, $find = null)    {        // if else 转换为代码执行        foreach ($condition as $judge) {            // 参数            $paramsArr = $judge['params'];            $resultBool = $parentCurrent = true;            foreach ($paramsArr as $key => $row) {                if (0 == $key) {                    $resultBool = $parentCurrent = $this->execExpression($data, $row);                } else {                    if ('and' == $row['type']) {                        if (true === $parentCurrent) {                            $resultBool = $parentCurrent = $this->execExpression($data, $row);                        } else {                            $resultBool = false;                            break;                        }                    } elseif ('or' == $row['type']) {                        if (true === $parentCurrent) {                            $resultBool = true;                            break;                        } else {                            $resultBool = $parentCurrent = $this->execExpression($data, $row);                        }                    }                }            }            if ($resultBool) { // 为真,执行内容                $manageCon = $judge['manageCon'];                foreach ($manageCon as $con) {                    $expressionResult = $this->execManageCon($data, $con);                    // 根据返回类型判断,有的需要直接返回,不再继续向下执行                    // 1 错误继续 2 错误退出 3 直接退出                    $back_type = $expressionResult['back_type'];                    $backResult = $expressionResult['result'] ?? [];                    $flag_uuid = $expressionResult['flag_uuid'] ?? '';                    $this->execResultArr[$flag_uuid] = $expressionResult;                    $this->requestData[$flag_uuid] = $backResult['result'];                    if (2 == $back_type) {                        if ($expressionResult['error']) { // 如果出现错误,则返回错误信息                            return $backResult;                        }                    } elseif (3 == $back_type) {                        break;                    }                }                // 停止条件语句                break;            }        }    }    /**     * 执行函数或表达式.     */    private function execExpression(array $data, array $row): bool    {        $operate = $row['operate'];        if ($row['isUseFn']) { // 使用函数            $fnName = $row['fnName'];            $fnParams = $row['fnParams'];            // 如果存在! 则先截取出来            preg_match('/^(!*)(.*)/', $fnName, $fnArr);            $flag = $fnArr[1];            $fnName = $fnArr[2];            foreach ($fnParams as $requestColumn) {                $val = Arr::get($data, $requestColumn);                if ($val) {                    $fParams[] = $val;                } else {                    $fParams[] = $requestColumn;                }            }            $result = $this->execFunc($fnName, $fParams);            if ($result) {                $current = true;            } else {                $current = false;            }            // ! 非操作符            if ($flag) {                if (1 == \strlen($flag) % 2) {                    $current = !$current;                }            }        } else { // 表达式            $requestVal = Arr::get($data, $row['params']);            if ($requestVal || 0 === $requestVal || true === $requestVal || false === $requestVal) {                $current = $this->getOperateResult($requestVal, $operate, $row['value']);            } else {                $current = false;            }        }        return $current;    }    /**     * 操作符的操作结果.     */    private function getOperateResult(mixed $requestVal, string $operate, mixed $value): bool    {        return match ($operate) {            'true' => true == $requestVal,            'false' => false == $requestVal,            '==' => $requestVal == $value,            '>' => $requestVal > $value,            '<' => $requestVal < $value,            '>=' => $requestVal >= $value,            '<=' => $requestVal <= $value,            '!=' => $requestVal != $value,            '===' => $requestVal === $value,            '!==' => $requestVal !== $value,            'in' => \in_array($value, $requestVal),            default => false,        };    }    /**     * 普通查询处理.     *     * @throws \GuzzleHttp\Exception\GuzzleException     */    private function execManageCon(array $data, array $con): array|null    {        $success_code = (isset($con['success_code']) && $con['success_code']) ? $con['success_code'] : 1001;        $success_msg = (isset($con['success_msg']) && $con['success_msg']) ? $con['success_msg'] : '恭喜你,操作成功!';        $failed_code = (isset($con['failed_code']) && $con['failed_code']) ? $con['failed_code'] : 2001;        $failed_msg = (isset($con['failed_msg']) && $con['failed_msg']) ? $con['failed_msg'] : '操作失败,请稍后再试!';        // 返回类型为5,直接返回,终止执行        if (5 == $con['back_type']) {            $backResult = backJson($failed_code, $failed_msg);            return ['error' => false, 'back_type' => $con['back_type'], 'result' => $backResult];        }        $requestParams = [];        if (isset($con['column']) && $con['column']) {            foreach ($con['column'] as $requestColumn) {                // 允许设置请求别名                $paramArr = explode(':', $requestColumn);                $column = $paramArr[0];                $requestColumn = $paramArr[1] ?? $column;                $val = Arr::get($data, $column);                $requestParams[$requestColumn] = $val;            }        }        $param_type = $con['param_type']; // 1 接口 2 函数 3 自定义接口        if (1 == $param_type) { // 接口            if (empty($con['interface_id'])) { // 不允许参数为空                abort(508, '结果集设置错误!- 接口地址不存在!');            }            $result = $this->execInterface($con['interface_id'], $requestParams);        } elseif (2 == $param_type) { // 函数            if (empty($con['fnName'])) { // 不允许参数为空                abort(508, '结果集设置错误!- 系统函数或方法不存在!');            }            $result = $this->execFunc($con['fnName'], array_values($requestParams));        } elseif (3 == $param_type) {  // 自定义接口            if (empty($con['url'])) { // 不允许参数为空                abort(508, '结果集设置错误!- 系统函数或方法不存在!');            }            // todo 可以在前端添加一个client请求设置菜单,可以设置微信支付接口,支付宝接口,百度网盘接口等等            $url = $con['url'];            $method = 'POST';            $options = [                'json' => $requestParams,                'timeout' => 60,                'verify' => false,            ];            if (!Str::startsWith($url, 'http')) {                if (Str::contains($url, '/')) {                    $url = secure_url($url);                } else {                    // 路由名生成一个 URL                    $url = route($url);                }            }            $client = new Client();            $result = $client->request($method, $url, $options);        }        if ($result instanceof JsonResponse) {            $backResult = json_decode($result->getContent(), true);            return ['error' => $backResult['error'], 'back_type' => $con['back_type'], 'flag_uuid' => $con['flag_uuid'] ?? '', 'result' => $backResult];        } elseif (empty($result) || (isset($result['error']) && $result['error'])) {            $backResult = backJson($result['code'] ?? $failed_code, $result['msg'] ?? $failed_msg);            return ['error' => true, 'back_type' => $con['back_type'], 'result' => $backResult];        } else {            $backResult = backJson($success_code, $success_msg, isset($result['error']) ? $result['result'] : $result);            return ['error' => false, 'back_type' => $con['back_type'], 'flag_uuid' => $con['flag_uuid'] ?? '', 'result' => $backResult];        }    }    /**     * 执行函数.     */    private function execFunc(string $function, array $params = []): mixed    {        if (empty($function)) {            abort(508, '结果集设置错误!- 函数为空');        }        if (($flag1 = Str::contains($function, '@')) || Str::contains($function, '::')) {            $arr = explode($flag1 ? '@' : '::', $function);            $class = $arr[0] ?? '';            $method = $arr[1] ?? 'handler';            if ($class && class_exists($class)) {                if ($flag1) {                    return \call_user_func_array([new $class($this->requestData, $this->interfaceInfo, $this->websiteInfo, $this->assembleInfo, $this->assembleColumns), $method], $params);                } else {                    return \call_user_func_array([$class, $method], $params);                }            } else {                abort(508, '接口参数设置错误!- 类【' . $class . '】不存在');            }        } elseif (\function_exists($function)) { // 如果是函数,则使用函数处理,参数:当前字段信息,接口信息,站点信息            return \call_user_func_array($function, $params);        }        return '';    }    /**     * 请求系统接口.     *     * @throws \Exception     */    private function execInterface(int $interfaceId, $requestParams = []): mixed    {        if (empty($interfaceId)) {            abort(508, '结果集设置错误!- 设置的接口为空!');        }        // 获取接口信息        $otherInterfaceInfo = DB::table('dep_interface')->find($interfaceId);        if ($otherInterfaceInfo) {            $interfaceService = new static($otherInterfaceInfo->en_alias, $this->websiteInfo);            $interfaceService->setRequestData($requestParams); // 设置参数            $errorMsg = $interfaceService->validator();            if ($errorMsg) {                abort(508, '结果集设置错误!- ' . $otherInterfaceInfo->en_alias . $errorMsg);            } else {                $response = $interfaceService->exec();                return json_decode($response->getContent(), true);            }        } else {            abort(508, '结果集设置错误!- 设置的接口不存在');        }    }    /**     * 获取字段关联的接口返回的数据.     *     * @throws \Exception     */    private function getChildrenInterfaceResult(array $row, array $relateInfo): mixed    {        $data = array_merge($this->requestData, ['&result' => $row]);        $relateInterfaceId = $relateInfo['interface_id'] ?? '';        if ($relateInterfaceId) {            // 获取接口信息            $interfaceInfo = DB::table('dep_interface')->find($relateInterfaceId);            $interfaceAlias = $interfaceInfo->en_alias;            // 参数设置            $requestParams = [];            foreach ($relateInfo['params'] as $item) {                // 允许设置请求别名                $paramArr = explode(':', $item);                $column = $paramArr[0];                $requestColumn = $paramArr[1] ?? $column;                $val = Arr::get($data, $column);                //如果没有设置别名,则正则替换 result 为 result_                $requestColumn = preg_replace('/&result\./', 'result_', $requestColumn);                $requestParams[$requestColumn] = $val;            }            // 请求接口            $interfaceService = new static($interfaceAlias, $this->websiteInfo);            $interfaceService->setRequestData($requestParams); // 优点,不会干扰现有的数据,除了固定参数外,其他参数允许接收,如果和固定参数有相同的key,则被覆盖            $errorMsg = $interfaceService->validator();            if ($errorMsg) {                // 为了不干扰原有字段                $row[$relateInfo['column']] = "error_" . $errorMsg;            } else {                $response = $interfaceService->exec();                $data = json_decode($response->getContent(), true);                $row[$relateInfo['column']] = $data['result'] ?? [];            }        }        return $row;    }    /**     * @param $ruleValue     *     * @return mixed     */    private function getRuleClass($ruleValue)    {        $class = ucfirst(Str::camel($ruleValue['rule']));        $class = '\\App\\Rules\\' . $class . 'Rule';        $ruleObj = new $class($this->table, $ruleValue, $this->websiteInfo['en_alias']);        // todo 可以在前端页面,设置自定义规则        if ($ruleObj instanceof EsUniqueRule) {            $operateType = $this->interfaceInfo['operate_type'];            if (2 === $operateType || 3 === $operateType) {                return (new EsUniqueRule($this->table, $ruleValue))->ignore($this->getRequestData('id'));            }        } elseif ($ruleObj instanceof EsExistsRule) {            return new EsExistsRule($this->table, $ruleValue);        }        return $ruleObj;    }}
 |