月度归档: 2022 年 3 月

  • 在 PhpStorm、Laravel 6 中,事件日志:Switch Laravel Idea module system to laravel-modules? Switch or don’t show this again

    在 PhpStorm、Laravel 6 中,事件日志:Switch Laravel Idea module system to laravel-modules? Switch or don’t show this again

    1、在 PhpStorm、Laravel 6 中,事件日志:Switch Laravel Idea module system to laravel-modules? Switch or don’t show this again。如图1

    在 PhpStorm、Laravel 6 中,事件日志:Switch Laravel Idea module system to laravel-modules? Switch or don't show this again。
    图1

    2、参考:https://laravel-idea.com/docs/modules 。Laravel Idea 使用模块系统概念来理解应用程序的结构。 它有助于正确完成视图、配置、路由和更方便的代码生成。项目的模块系统可以在 File | 设置 | 语言和框架 | Laravel 理念 | 模块系统 找到。如图2

    参考:https://laravel-idea.com/docs/modules 。Laravel Idea 使用模块系统概念来理解应用程序的结构。 它有助于正确完成视图、配置、路由和更方便的代码生成。项目的模块系统可以在 File | 设置 | 语言和框架 | Laravel 理念 | 模块系统 找到。
    图2

    3、nWidart/laravel-modules 包,使用 nWidart/laravel-modules 包构建的应用程序的模块系统。最终决定选择此选项。因为现在程序的模块系统依赖于 nWidart/laravel-modules。点击 Switch。模块系统切换成功。 如果出现完成问题,请选择“文件 > 使缓存无效并重新启动…”。如图3

    nWidart/laravel-modules 包,使用 nWidart/laravel-modules 包构建的应用程序的模块系统。最终决定选择此选项。因为现在程序的模块系统依赖于 nWidart/laravel-modules。点击 Switch。模块系统切换成功。 如果出现完成问题,请选择“文件 > 使缓存无效并重新启动...”。
    图3

    4、文件 > 清除缓存 > 清除并重新启动。如图4

    文件 > 清除缓存 > 清除并重新启动。
    图4
  • 在 Laravel 6 中报错:Target [Interface] is not instantiable while building [Resolver]

    在 Laravel 6 中报错:Target [Interface] is not instantiable while building [Resolver]

    1、在 Laravel 6 中报错:Target [Interface] is not instantiable while building [Resolver]。如图1
    在 Laravel 6 中报错:Target [Interface] is not instantiable while building [Resolver]。
    图1
    
    
    {
        "message": "Target [Modules\\ThemeSetting\\Schema\\ThemeSchemaLoaderInterface] is not instantiable while building [Modules\\ThemeStore\\Resolver\\OnlineStoreThemeResolver].",
        "exception": "Illuminate\\Contracts\\Container\\BindingResolutionException",
        "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
        "line": 978,
        "trace": [
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 812,
                "function": "notInstantiable",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 681,
                "function": "build",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Application.php",
                "line": 785,
                "function": "resolve",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 629,
                "function": "resolve",
                "class": "Illuminate\\Foundation\\Application",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Application.php",
                "line": 770,
                "function": "make",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 945,
                "function": "make",
                "class": "Illuminate\\Foundation\\Application",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 873,
                "function": "resolveClass",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 834,
                "function": "resolveDependencies",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 681,
                "function": "build",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Application.php",
                "line": 785,
                "function": "resolve",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
                "line": 629,
                "function": "resolve",
                "class": "Illuminate\\Foundation\\Application",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Application.php",
                "line": 770,
                "function": "make",
                "class": "Illuminate\\Container\\Container",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\helpers.php",
                "line": 120,
                "function": "make",
                "class": "Illuminate\\Foundation\\Application",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Utils.php",
                "line": 58,
                "function": "app"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\FieldDirective.php",
                "line": 45,
                "function": "constructResolver",
                "class": "Nuwave\\Lighthouse\\Support\\Utils",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Factories\\FieldFactory.php",
                "line": 68,
                "function": "resolveField",
                "class": "Nuwave\\Lighthouse\\Schema\\Directives\\FieldDirective",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\TypeRegistry.php",
                "line": 369,
                "function": "handle",
                "class": "Nuwave\\Lighthouse\\Schema\\Factories\\FieldFactory",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Type\\Definition\\UnresolvedFieldDefinition.php",
                "line": 39,
                "function": "Nuwave\\Lighthouse\\Schema\\{closure}",
                "class": "Nuwave\\Lighthouse\\Schema\\TypeRegistry",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Type\\Definition\\TypeWithFields.php",
                "line": 45,
                "function": "resolve",
                "class": "GraphQL\\Type\\Definition\\UnresolvedFieldDefinition",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Type\\Definition\\TypeWithFields.php",
                "line": 33,
                "function": "findField",
                "class": "GraphQL\\Type\\Definition\\TypeWithFields",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Validator\\Rules\\OverlappingFieldsCanBeMerged.php",
                "line": 256,
                "function": "getField",
                "class": "GraphQL\\Type\\Definition\\TypeWithFields",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Validator\\Rules\\OverlappingFieldsCanBeMerged.php",
                "line": 165,
                "function": "internalCollectFieldsAndFragmentNames",
                "class": "GraphQL\\Validator\\Rules\\OverlappingFieldsCanBeMerged",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Validator\\Rules\\OverlappingFieldsCanBeMerged.php",
                "line": 96,
                "function": "getFieldsAndFragmentNames",
                "class": "GraphQL\\Validator\\Rules\\OverlappingFieldsCanBeMerged",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Validator\\Rules\\OverlappingFieldsCanBeMerged.php",
                "line": 64,
                "function": "findConflictsWithinSelectionSet",
                "class": "GraphQL\\Validator\\Rules\\OverlappingFieldsCanBeMerged",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Language\\Visitor.php",
                "line": 414,
                "function": "GraphQL\\Validator\\Rules\\{closure}",
                "class": "GraphQL\\Validator\\Rules\\OverlappingFieldsCanBeMerged",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Language\\Visitor.php",
                "line": 470,
                "function": "GraphQL\\Language\\{closure}",
                "class": "GraphQL\\Language\\Visitor",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Language\\Visitor.php",
                "line": 277,
                "function": "GraphQL\\Language\\{closure}",
                "class": "GraphQL\\Language\\Visitor",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Validator\\DocumentValidator.php",
                "line": 224,
                "function": "visit",
                "class": "GraphQL\\Language\\Visitor",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Validator\\DocumentValidator.php",
                "line": 116,
                "function": "visitUsingRules",
                "class": "GraphQL\\Validator\\DocumentValidator",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
                "line": 153,
                "function": "validate",
                "class": "GraphQL\\Validator\\DocumentValidator",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
                "line": 94,
                "function": "promiseToExecute",
                "class": "GraphQL\\GraphQL",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
                "line": 268,
                "function": "executeQuery",
                "class": "GraphQL\\GraphQL",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
                "line": 203,
                "function": "executeParsedQuery",
                "class": "Nuwave\\Lighthouse\\GraphQL",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
                "line": 162,
                "function": "parseAndExecuteQuery",
                "class": "Nuwave\\Lighthouse\\GraphQL",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
                "line": 121,
                "function": "executeOperation",
                "class": "Nuwave\\Lighthouse\\GraphQL",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Utils.php",
                "line": 99,
                "function": "Nuwave\\Lighthouse\\{closure}",
                "class": "Nuwave\\Lighthouse\\GraphQL",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
                "line": 120,
                "function": "applyEach",
                "class": "Nuwave\\Lighthouse\\Support\\Utils",
                "type": "::"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Controllers\\GraphQLController.php",
                "line": 32,
                "function": "executeOperationOrOperations",
                "class": "Nuwave\\Lighthouse\\GraphQL",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php",
                "line": 48,
                "function": "__invoke",
                "class": "Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
                "line": 219,
                "function": "dispatch",
                "class": "Illuminate\\Routing\\ControllerDispatcher",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
                "line": 176,
                "function": "runController",
                "class": "Illuminate\\Routing\\Route",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
                "line": 681,
                "function": "run",
                "class": "Illuminate\\Routing\\Route",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 130,
                "function": "Illuminate\\Routing\\{closure}",
                "class": "Illuminate\\Routing\\Router",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AttemptAuthentication.php",
                "line": 34,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AttemptAuthentication",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AcceptJson.php",
                "line": 27,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AcceptJson",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 105,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
                "line": 683,
                "function": "then",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
                "line": 658,
                "function": "runRouteWithinStack",
                "class": "Illuminate\\Routing\\Router",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
                "line": 624,
                "function": "runRoute",
                "class": "Illuminate\\Routing\\Router",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
                "line": 613,
                "function": "dispatchToRoute",
                "class": "Illuminate\\Routing\\Router",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
                "line": 170,
                "function": "dispatch",
                "class": "Illuminate\\Routing\\Router",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 130,
                "function": "Illuminate\\Foundation\\Http\\{closure}",
                "class": "Illuminate\\Foundation\\Http\\Kernel",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\barryvdh\\laravel-debugbar\\src\\Middleware\\InjectDebugbar.php",
                "line": 67,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Barryvdh\\Debugbar\\Middleware\\InjectDebugbar",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\app\\Http\\Middleware\\ChangeAppUrlMiddleware.php",
                "line": 23,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "App\\Http\\Middleware\\ChangeAppUrlMiddleware",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
                "line": 21,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
                "line": 21,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
                "line": 27,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php",
                "line": 63,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
                "line": 57,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Fideloper\\Proxy\\TrustProxies",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\dingo\\api\\src\\Http\\Middleware\\Request.php",
                "line": 111,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 171,
                "function": "handle",
                "class": "Dingo\\Api\\Http\\Middleware\\Request",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
                "line": 105,
                "function": "Illuminate\\Pipeline\\{closure}",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
                "line": 145,
                "function": "then",
                "class": "Illuminate\\Pipeline\\Pipeline",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
                "line": 110,
                "function": "sendRequestThroughRouter",
                "class": "Illuminate\\Foundation\\Http\\Kernel",
                "type": "->"
            },
            {
                "file": "E:\\wwwroot\\object\\public\\index.php",
                "line": 57,
                "function": "handle",
                "class": "Illuminate\\Foundation\\Http\\Kernel",
                "type": "->"
            }
        ]
    }
    
    
    
    2、查看 /Modules/ThemeStore/Providers/ThemeStoreServiceProvider.php,提示 未定义的类 ‘ThemeSchemaLoaderInterface’。如图2
    查看 /Modules/ThemeStore/Providers/ThemeStoreServiceProvider.php,提示 未定义的类 'ThemeSchemaLoaderInterface'。
    图2
    3、但是,可以确认 类 ‘ThemeSchemaLoaderInterface’ 是存在的。最后发现 use 的路径有误。删掉掉路径中的 Theme\。IDE 不再提示。如图3
    但是,可以确认 类 'ThemeSchemaLoaderInterface' 是存在的。最后发现 use 的路径有误。删掉掉路径中的 Theme\。IDE 不再提示。
    图3
    4、执行命令:php artisan list 时报错:Illuminate\Contracts\Container\BindingResolutionException : Target class [Modules\ThemeStore\Console\AssetCdn\SyncCommand] does not exist.
    
    
    PS E:\wwwroot\object> php artisan list
    
       Illuminate\Contracts\Container\BindingResolutionException  : Target class [Modules\ThemeStore\Console\AssetCdn\SyncCommand] does not exist.
    
      at E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Container\Container.php:805
        801|
        802|         try {
        803|             $reflector = new ReflectionClass($concrete);
        804|         } catch (ReflectionException $e) {
      > 805|             throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
        806|         }
        807|
        808|         // If the type is not instantiable, the developer is attempting to resolve
        809|         // an abstract type such as an Interface or Abstract Class and there is
    
      Exception trace:
    
      1   ReflectionException::("Class Modules\ThemeStore\Console\AssetCdn\SyncCommand does not exist")
          E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Container\Container.php:803
    
      2   ReflectionClass::__construct("Modules\ThemeStore\Console\AssetCdn\SyncCommand")
          E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Container\Container.php:803
    
      Please use the argument -v to see more details.
    PS E:\wwwroot\object>
    
    
    
    
    5、查看 /Modules/ThemeStore/Providers/ThemeStoreServiceProvider.php ,确定 Consoles\AssetCdn\SyncCommand::class 在相应路径下不存在。删除掉相应的调用。如图4
    查看 /Modules/ThemeStore/Providers/ThemeStoreServiceProvider.php ,确定 Consoles\AssetCdn\SyncCommand::class 在相应路径下不存在。删除掉相应的调用。
    图4
    6、再次执行命令:php artisan list 时成功。
  • 模板文件的验证规则:文件大小限制的分析

    模板文件的验证规则:文件大小限制的分析

    1、参考 Shopify 后台的模板源码编辑,当上传一个大于 50 MB 的文件时,响应 413 Request Entity Too Large。这应该是 Nginx 的 server 中:client_max_body_size 50M 的设置所限制。如图1

    参考 Shopify 后台的模板源码编辑,当上传一个大于 50 MB 的文件时,响应 413 Request Entity Too Large。这应该是 Nginx 的 server 中:client_max_body_size 50M 的设置所限制。
    图1

    2、当上传一个 48.5 MB 的 css 文件时,耗时 2 分钟,上传成功,响应 200。如图2

    当上传一个 48.5 MB 的 css 文件时,耗时 2 分钟,上传成功,响应 200。
    图2

    3、当新增或编辑一个 368 KB 的 liquid、json 文件时,响应 422。模板内容超出 256 KB 的限制。如图3

    当新增或编辑一个 368 KB 的 liquid、json 文件时,响应 422。模板内容超出 256 KB 的限制。
    图3

    4、当在 Assets 下新增一个空白文件 1.css.liquid 后,再编辑时,添加内容大小为 1.81 MB 。保存成功。

    5、在 WordPress 后台的外观 – 主题文件编辑器中编辑 Hueman: 首页模板 (index.php),当添加了 736 KB 的内容后,更新成功,响应 200。耗时 1.5 秒。如图5

    在 WordPress 后台的外观 - 主题文件编辑器中编辑 Hueman: 首页模板 (index.php),当添加了 736 KB 的内容后,更新成功,响应 200。耗时 1.5 秒。
    图5

    6、当添加了大于 50 MB 的内容时,响应 502。出现了问题,您的修改可能未被保存,请重试。您也可能需要通过FTP手工修复并上传文件。查看网络中的响应:无法加载响应数据: Request content was evicted from inspector cache。确认新添加的内容已经成功保存至模板文件中。通过重新查看模板文件内容确认。如图6

    当添加了大于 50 MB 的内容时,响应 502。出现了问题,您的修改可能未被保存,请重试。您也可能需要通过FTP手工修复并上传文件。查看网络中的响应:无法加载响应数据: Request content was evicted from inspector cache。确认新添加的内容已经成功保存至模板文件中。通过重新查看模板文件内容确认。
    图6

    7、当添加了 46.5 MB 的内容时,响应 502。最后一直到 22.8 MB ,皆响应 502。到 22.7 MB,响应 200。

    8、搜索 WordPress 中主题目录下的 .php 文件,其中最大的文件其大小为:1.59 MB。搜索 WordPress 中主题目录:的 .js 文件,其中最大的文件其大小为:402 KB。搜索 WordPress 中主题目录:的 .png 文件,其中最大的文件其大小为:911 KB。如图7

    搜索 WordPress 中主题目录下的 .php 文件,其中最大的文件其大小为:1.59 MB。搜索 WordPress 中主题目录:的 .js 文件,其中最大的文件其大小为:402 KB。搜索 WordPress 中主题目录:的 .png 文件,其中最大的文件其大小为:911 KB。
    图7

    9、最后制定出自身的规则:Assets 目录下的文件的大小限制为 10 MB(MySQL MEDIUMBLOB 限制为 16 MB),Locales 目录下的文件的大小限制为 2 MB,其他目录下的文件的大小限制为 512 KB。

  • 在 PHP 中实现文件路径名(编辑模板代码时,可新增文件)的安全验证

    在 PHP 中实现文件路径名(编辑模板代码时,可新增文件)的安全验证

    1、查看请求参数:asset[key]: assets/2022/02/25.css,准备在模板文件中新增文件:assets/2022/02/25.css。响应失败:Theme files may not be stored in subfolders。如图1

    查看请求参数:asset[key]: assets/2022/02/25.css,准备在模板文件中新增文件:assets/2022/02/25.css。响应失败:Theme files may not be stored in subfolders。
    图1

    2、查看请求参数:asset[key]: assets/25.css,准备在模板文件中新增文件:assets/25.css。响应成功。如图2

    查看请求参数:asset[key]: assets/25.css,准备在模板文件中新增文件:assets/25.css。响应成功。
    图2

    3、查看请求参数:asset[key]: assets/02\25.css,准备在模板文件中新增文件:assets/02\25.css。响应失败:”assets/02\\25.css” contains illegal characters。如图3

    查看请求参数:asset[key]: assets/02\25.css,准备在模板文件中新增文件:assets/02\25.css。响应失败:"assets/02\\25.css" contains illegal characters。
    图3

    4、查看请求参数:asset[key]: templates/customers/order.order1.liquid,准备在模板文件中新增文件:templates/customers/order.order1.liquid。响应成功。目录:templates/customers 早已经生成好。如图4

    查看请求参数:asset[key]: templates/customers/order.order1.liquid,准备在模板文件中新增文件:templates/customers/order.order1.liquid。响应成功。目录:templates/customers 早已经生成好。
    图4

    5、最终整理出的验证规则如下:
    (1)路径参数必须以已经生成好的目录开头。目录包含:[‘layouts/’, ‘auth/’, ‘pages/’, ‘components/’, ‘assets/’, ‘js/’, ‘sass/’, ‘assets/iconfont/’, ‘js/common/’, ‘js/view/’, ‘js/view/account/’, ‘js/view/cart/’, ‘js/view/collections/’, ‘js/view/product/’, ‘js/view/productlist/’, ‘js/view/search/’]
    (2)当 asset[key] 去掉目录开头部分后,便仅需要验证纯粹的文件名,不允许再包含 / 与 \
    (3)验证 asset[key] 的文件扩展名,其文件后缀名必须属于一个预先定义的数组中,扩展名包含:[‘.php’, ‘.json’, ‘.css’, ‘.scss’, ‘.js’, ‘.vue’]

    6、难点主要在于第 2 条验证规则的实现,参考:https://stackoverflow.com/questions/31089394/check-if-string-is-valid-filename 。POSIX“完全可移植的文件名”列出了这些:A-Z a-z 0-9 . _ – 。新建文件:FilePathValidator.php,不允许空格。

    <?php
    function validate($filename) {
        if (preg_match('/^[\w\-.]+$/', $filename)) { 
            return $filename . ' 验证成功';
        } else {
            return $filename . ' 验证失败';
        }
    }
     
    $filenames = ['assets/2022/02/25.css', 'assets/02\25.css', '/25.css', '25.css/', '2_- 5.css', '2_-5.css', '中国.css', 'testjpg.', '.testjpg', 'test.jpg'];
    foreach ($filenames as $filename) {
        echo validate($filename) . PHP_EOL;
    }
    ?>
    

    7、查看运行结果,验证成功的 3 个文件名中,需要再排除掉:testjpg.、.testjpg,而第 3 条验证规则恰好可以排队掉:testjpg.、.testjpg。目录开头与文件扩展名结尾,可以使用 dirname() 与 Laravel 中的验证方法:ends_with:foo,bar,… 验证的字段必须以给定的值之一结尾。如图5

    查看运行结果,验证成功的 3 个文件名中,需要再排除掉:testjpg.、.testjpg,而第 3 条验证规则恰好可以排队掉:testjpg.、.testjpg。目录开头与文件扩展名结尾,可以使用 dirname() 与 Laravel 中的验证方法:ends_with:foo,bar,… 验证的字段必须以给定的值之一结尾。
    图5
    
    assets/2022/02/25.css 验证失败
    assets/02\25.css 验证失败
    /25.css 验证失败
    25.css/ 验证失败
    2_- 5.css 验证失败
    2_-5.css 验证成功
    中国.css 验证失败
    testjpg. 验证成功
    .testjpg 验证成功
    test.jpg 验证成功
    
    
    
        /**
         * Return the validation rules.
         *
         * @return array<string, array<mixed>>
         */
        public function rules(): array
        {
            $extensions = implode(",", ThemeAsset::BLADE_EXTENSIONS);
            return [
                'key' => [
                    // 当获取文件路径中的目录部分后,其必须属于目录列表之一
                    function ($attribute, $value, $fail) {
                        if (!in_array(dirname($value) . '/', ThemeAsset::BLADE_DIRS)) {
                            $fail('The directory portion of ' . $attribute . ' can only contain the following: ' . implode(", ", ThemeAsset::BLADE_DIRS));
                        }
                    },
                    // 当获取文件路径中的文件名部分后,便仅需要验证纯粹的文件名,只允许包含:A-Z、a-z、0-9、.、_、-
                    function ($attribute, $value, $fail) {
                        if (!preg_match('/^[\w\-.]+$/', basename($value))) {
                            $fail('The file name portion of ' . $attribute . ' can only contain the following: A-Z, a-z, 0-9, ., _, -');
                        }
                    },
                    // 验证的字段必须以给定的值之一结尾
                    'ends_with:' . $extensions,
                ],
            ];
        }
    

    8、这会过滤掉不属于 ISO-1252 的有效文件名,例如日文、中文、西欧、西里尔文、中东……字符。 此外,它不会过滤掉具有有效字符但在操作系统中无效的文件名,例如 COM1、LPT1、AUX …。此二项缺陷暂时皆可以接受。后续可能会解决不会过滤掉具有有效字符但在操作系统中无效的文件名。如图6

    这会过滤掉不属于 ISO-1252 的有效文件名,例如日文、中文、西欧、西里尔文、中东......字符。 此外,它不会过滤掉具有有效字符但在操作系统中无效的文件名,例如 COM1、LPT1、AUX ...。此二项缺陷暂时皆可以接受。后续可能会解决不会过滤掉具有有效字符但在操作系统中无效的文件名。
    图6
  • 在 Laravel 6、Module、Lighthouse 中实现 安全 验证 的流程(使用验证器类来支持复杂的验证规则)

    在 Laravel 6、Module、Lighthouse 中实现 安全 验证 的流程(使用验证器类来支持复杂的验证规则)

    1、当请求响应成功时的结构。如图1

    当请求响应成功时的结构。
    图1
    
    
    mutation {
      onlineStoreThemeAssetCreate(
        input: { themeId: "vogue", content: "string", key: "string" }
      ) {
        themeAsset {
          id
          themeId
          content
          key
          mimeType
          category
          schema
          createdAt
          updatedAt
          deletable
          renameable
          updatable
        }
      }
    }
    
    
    
    
    
    {
      "data": {
        "onlineStoreThemeAssetCreate": {
          "themeAsset": {
            "id": "653",
            "themeId": "vogue",
            "content": "string",
            "key": "string",
            "mimeType": "text/x-php",
            "category": "unknown",
            "schema": null,
            "createdAt": "2022-02-25 01:49:53",
            "updatedAt": "2022-02-25 01:49:53",
            "deletable": false,
            "renameable": false,
            "updatable": false
          }
        }
      }
    }
    
    
    

    2、但是,现阶段并未针对请求参数进行安全验证。参考:https://lighthouse-php.com/master/security/validation.html#single-arguments 。Lighthouse 允许您在查询和变更中使用 Laravel 的验证。如图2

    但是,现阶段并未针对请求参数进行安全验证。参考:https://lighthouse-php.com/master/security/validation.html#single-arguments 。Lighthouse 允许您在查询和变更中使用 Laravel 的验证。
    图2

    3、此 GraphQL API 的变更虽然在输入对象中仅有 3 个参数,但是验证规则比较复杂。包含如下规则:
    (1)验证表中是否存在 themeId: “vogue” 的记录,如果不存在,验证失败;

    
    SELECT * FROM `object_store`.`theme_asset` WHERE `theme_id` = 'vogue' LIMIT 0,1
    
    
    

    (2)验证 key: “string” 的格式,其必须为一个有效的相对路径,例:assets/iconfont/iconfont.css。其值等于 string ,验证失败;
    (3)验证 key: “string” 的格式,其为一个有效的相对路径后,其文件后缀名必须属于一个预先定义的数组中,例:[‘json’, ‘css’, ‘js’];
    (4)验证表中 themeId: “vogue”, key: “string” 记录的唯一性,如果已存在,验证失败;

    
    SELECT * FROM `object_store`.`theme_asset` WHERE `theme_id` = 'vogue' AND `asset_key` = 'string' LIMIT 0,1
    
    
    

    (5)验证 content: “string” 的格式,例:当 key 的值的文件后缀名为 .json 时,需要验证 content 的值格式为 json 格式;
    (6)mime_type 的值需要基于 key 的值转换得出;
    (7)category 的值需要基于 key 的值转换得出;

    4、使用验证器类来支持复杂的验证规则。Lighthouse 对验证器类使用简单的命名约定,只需使用输入类型的名称并附加 Validator 。最终生成文件:/app/GraphQL/Validators/CreateOnlineStoreThemeAssetInputValidator.php

    
    PS E:\wwwroot\lighthouse-tutorial> php artisan lighthouse:validator CreateOnlineStoreThemeAssetInputValidator
    Validator created successfully.
    
    
    

    5、由于现在需要在 Module ThemeStore 中使用此验证器类,将文件:/app/GraphQL/Validators/CreateOnlineStoreThemeAssetInputValidator.php 剪切至:/Modules/ThemeStore/Validators/CreateOnlineStoreThemeAssetInputValidator.php

    <?php
     
    namespace Modules\ThemeStore\Validators;
     
    use Nuwave\Lighthouse\Validation\Validator;
     
    class CreateOnlineStoreThemeAssetInputValidator extends Validator
    {
        /**
         * Return the validation rules.
         *
         * @return array<string, array<mixed>>
         */
        public function rules(): array
        {
            return [
                'themeId' => [
                    'exists:theme_asset,theme_id'
                ],
            ];
        }
    }
    

    6、编辑文件:/Modules/ThemeStore/Resources/graphql/theme_asset.graphql,修改输入对象,使用 @validator 指令,以指定验证器类

    
    input OnlineStoreThemeAssetCreateInput @validator(class: "Modules\\ThemeStore\\Validators\\CreateOnlineStoreThemeAssetInputValidator") {
        "主题ID"
        themeId: String!,
        "内容"
        content: String!,
        "路径,相对于主题的路径,如 pages/index.blade.php"
        key: String!,
    }
    
    
    

    7、测试验证规则是否有效,确定有效。如图3

    测试验证规则是否有效,确定有效。
    图3
    
    
    mutation {
      onlineStoreThemeAssetCreate(
        input: { themeId: "vogue1", content: "string", key: "string" }
      ) {
        themeAsset {
          id
          themeId
          content
          key
          mimeType
          category
          schema
          createdAt
          updatedAt
          deletable
          renameable
          updatable
        }
      }
    }
    
    
    
    
    
    {
      "errors": [
        {
          "message": "Validation failed for the field [onlineStoreThemeAssetCreate].",
          "extensions": {
            "validation": {
              "input.themeId": [
                "The selected input.theme id is invalid."
              ]
            },
            "category": "validation"
          },
          "locations": [
            {
              "line": 2,
              "column": 3
            }
          ],
          "path": [
            "onlineStoreThemeAssetCreate"
          ],
          "trace": [
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\ArgTraversalDirective.php",
              "line": 29,
              "call": "Nuwave\\Lighthouse\\Validation\\ValidateDirective::Nuwave\\Lighthouse\\Validation\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\TrimDirective.php",
              "line": 56,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\ArgTraversalDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Factories\\FieldFactory.php",
              "line": 99,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\TrimDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 623,
              "call": "Nuwave\\Lighthouse\\Schema\\Factories\\FieldFactory::Nuwave\\Lighthouse\\Schema\\Factories\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 550,
              "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, instance of Closure, null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 474,
              "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: Mutation, null, instance of ArrayObject(1), array(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 857,
              "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeAssetCreate')"
            },
            {
              "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeAssetCreate')"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 859,
              "function": "array_reduce(array(1), instance of Closure, array(0))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 490,
              "call": "GraphQL\\Executor\\ReferenceExecutor::promiseReduce(array(1), instance of Closure, array(0))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 263,
              "call": "GraphQL\\Executor\\ReferenceExecutor::executeFieldsSerially(GraphQLType: Mutation, null, array(0), instance of ArrayObject(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 215,
              "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\Executor.php",
              "line": 156,
              "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
              "line": 162,
              "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
              "line": 94,
              "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 268,
              "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 203,
              "call": "Nuwave\\Lighthouse\\GraphQL::executeParsedQuery(instance of GraphQL\\Language\\AST\\DocumentNode, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 162,
              "call": "Nuwave\\Lighthouse\\GraphQL::parseAndExecuteQuery('mutation {\n  onlineStoreThemeAssetCreate(\n    input: { themeId: \"vogue1\", content: \"string\", key: \"string\" }\n  ) {\n    themeAsset {\n      id\n      themeId\n      content\n      key\n      mimeType\n      category\n      schema\n      createdAt\n      updatedAt\n      deletable\n      renameable\n      updatable\n    }\n  }\n}', instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 121,
              "call": "Nuwave\\Lighthouse\\GraphQL::executeOperation(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Utils.php",
              "line": 99,
              "call": "Nuwave\\Lighthouse\\GraphQL::Nuwave\\Lighthouse\\{closure}(instance of GraphQL\\Server\\OperationParams)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 120,
              "call": "Nuwave\\Lighthouse\\Support\\Utils::applyEach(instance of Closure, instance of GraphQL\\Server\\OperationParams)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Controllers\\GraphQLController.php",
              "line": 32,
              "call": "Nuwave\\Lighthouse\\GraphQL::executeOperationOrOperations(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php",
              "line": 48,
              "call": "Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController::__invoke(instance of Illuminate\\Http\\Request, instance of Nuwave\\Lighthouse\\GraphQL, instance of Illuminate\\Events\\Dispatcher, instance of Laragraph\\Utils\\RequestParser, instance of Nuwave\\Lighthouse\\Execution\\SingleResponse, instance of Nuwave\\Lighthouse\\Execution\\ContextFactory)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
              "line": 219,
              "call": "Illuminate\\Routing\\ControllerDispatcher::dispatch(instance of Illuminate\\Routing\\Route, instance of Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController, '__invoke')"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
              "line": 176,
              "call": "Illuminate\\Routing\\Route::runController()"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 681,
              "call": "Illuminate\\Routing\\Route::run()"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 130,
              "call": "Illuminate\\Routing\\Router::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AttemptAuthentication.php",
              "line": 34,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AttemptAuthentication::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AcceptJson.php",
              "line": 27,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AcceptJson::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 105,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 683,
              "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 658,
              "call": "Illuminate\\Routing\\Router::runRouteWithinStack(instance of Illuminate\\Routing\\Route, instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 624,
              "call": "Illuminate\\Routing\\Router::runRoute(instance of Illuminate\\Http\\Request, instance of Illuminate\\Routing\\Route)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 613,
              "call": "Illuminate\\Routing\\Router::dispatchToRoute(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
              "line": 170,
              "call": "Illuminate\\Routing\\Router::dispatch(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 130,
              "call": "Illuminate\\Foundation\\Http\\Kernel::Illuminate\\Foundation\\Http\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\barryvdh\\laravel-debugbar\\src\\Middleware\\InjectDebugbar.php",
              "line": 67,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Barryvdh\\Debugbar\\Middleware\\InjectDebugbar::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\app\\Http\\Middleware\\ChangeAppUrlMiddleware.php",
              "line": 23,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "App\\Http\\Middleware\\ChangeAppUrlMiddleware::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
              "line": 21,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
              "line": 21,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
              "line": 27,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php",
              "line": 63,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
              "line": 57,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Fideloper\\Proxy\\TrustProxies::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\dingo\\api\\src\\Http\\Middleware\\Request.php",
              "line": 111,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Dingo\\Api\\Http\\Middleware\\Request::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 105,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
              "line": 145,
              "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
              "line": 110,
              "call": "Illuminate\\Foundation\\Http\\Kernel::sendRequestThroughRouter(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\public\\index.php",
              "line": 57,
              "call": "Illuminate\\Foundation\\Http\\Kernel::handle(instance of Illuminate\\Http\\Request)"
            }
          ]
        }
      ],
      "data": {
        "onlineStoreThemeAssetCreate": null
      }
    }
    
    
    

    8、查看 Laravel Telescope 中请求中的 SQL 语句。如图4

    查看 Laravel Telescope 中请求中的 SQL 语句。
    图4
    
    select count(*) as aggregate from `theme_asset` where `theme_id` = 'vogue1'
    
    
    
  • 从 REST 迁移到 GraphQL 的一些思考与实践(创建资源),参考 Shopify

    从 REST 迁移到 GraphQL 的一些思考与实践(创建资源),参考 Shopify

    1、新增 template ,创建模板。如图1
    新增 template ,创建模板。
    图1
    2、点击保存按钮,查看网络请求。请求网址: https://xxx.myshopify.com/admin/themes/111/assets 。请求方法: POST。这是 REST 实现。如图2
    点击保存按钮,查看网络请求。请求网址: https://xxx.myshopify.com/admin/themes/111/assets 。请求方法: POST。这是 REST 实现。
    图2
    请求的表单数据:
    
    
    asset[key]: templates/article.dawn2.json
    asset[value]: {
      "sections": {
        "main": {
          "type": "main-article",
          "blocks": {
            "featured_image": {
              "type": "featured_image",
              "settings": {
              }
            },
            "title": {
              "type": "title",
              "settings": {
              }
            },
            "content": {
              "type": "content",
              "settings": {
              }
            },
            "share": {
              "type": "share",
              "settings": {
              }
            }
          },
          "block_order": [
            "featured_image",
            "title",
            "share",
            "content"
          ],
          "settings": {
          }
        }
      },
      "order": [
        "main"
      ]
    }
    
    
    
    响应数据:
    
    
    {
        "asset": {
            "key": "templates\/article.dawn2.json",
            "public_url": null,
            "created_at": "2022-02-22T22:23:17-08:00",
            "updated_at": "2022-02-22T22:23:17-08:00",
            "content_type": "application\/json",
            "size": 324,
            "checksum": "125d46765a7b7f96e7f3992a8bcfe22e",
            "theme_id": 128094896334
        }
    }
    
    
    
    3、在 GraphQL 中未实现创建模板文件的 API。决定参考 productCreate ( input ProductInput!, media [CreateMediaInput!] ) ProductCreatePayload Creates a product.。如图3
    在 GraphQL 中未实现创建模板文件的 API。决定参考 productCreate ( input ProductInput!, media [CreateMediaInput!] ) ProductCreatePayload Creates a product.。
    图3
    4、测试请求与响应结构,先测试响应失败的结构。如图4
    测试请求与响应结构,先测试响应失败的结构。
    图4
    请求数据:
    
    
    mutation {
      productCreate(
        input: {title: "title"} {
          ... product
          ... userErrors
        }
    }
    
    fragment product on ProductCreatePayload {
      product {
        status
        storefrontId
        tags
        templateSuffix
        title
        totalInventory
        totalVariants
        tracksInventory
      }
    }
    
    fragment userErrors on ProductCreatePayload {
      userErrors {
        field
        message
      }
    }
    
    
    
    
    响应数据:
    
    
    {
      "errors": [
        {
          "message": "Parse error on \"{\" (LCURLY) at [3, 29]",
          "locations": [
            {
              "line": 3,
              "column": 29
            }
          ]
        }
      ]
    }
    
    
    
    5、测试请求与响应结构,测试响应成功的结构。但是响应失败。如图5
    测试请求与响应结构,测试响应成功的结构。但是响应失败。
    图5
    请求数据:
    
    
    mutation {
      productCreate(
        input: {
          title: "标题 20220223 2",
      	}
      ) {
        product {
          ... product
          ... userErrors
        }
    }
    
    fragment product on ProductCreatePayload {
      product {
        title
      }
    }
    
    fragment userErrors on ProductCreatePayload {
      userErrors {
        field
        message
      }
    }
    
    
    
    
    
    响应数据:
    
    
    {
      "errors": [
        {
          "message": "Unexpected end of document",
          "locations": []
        }
      ]
    }
    
    
    
    6、决定在 Shopify 后台 手动添加一件产品,查看网络请求,其是请求的 GraphQL API,参考其请求参数,复制至 Altair 的请求中。点击选择 query,然后右键复制值。如图6
    决定在 Shopify 后台 手动添加一件产品,查看网络请求,其是请求的 GraphQL API,参考其请求参数,复制至 Altair 的请求中。点击选择 query,然后右键复制值。
    图6
    7、粘贴至 Altair 的查询中。如图7
    粘贴至 Altair 的查询中。
    图7
    
    
    mutation CreateProduct($product: ProductInput!, $media: [CreateMediaInput!]) {
      productCreate(input: $product, media: $media) {
        product {
          id
          title
          handle
          descriptionHtml
          resourceAlerts {
            content
            dismissed
            dismissibleHandle
            severity
            title
            actions {
              primary
              title
              url
              __typename
            }
            __typename
          }
          firstVariant: variants(first: 1) {
            edges {
              node {
                id
                requiresShipping
                weight
                weightUnit
                barcode
                sku
                inventoryPolicy
                fulfillmentService {
                  id
                  __typename
                }
                inventoryItem {
                  id
                  unitCost {
                    amount
                    __typename
                  }
                  countryCodeOfOrigin
                  provinceCodeOfOrigin
                  harmonizedSystemCode
                  tracked
                  __typename
                }
                ...PricingCardVariant
                __typename
              }
              __typename
            }
            __typename
          }
          ...SEOCardProduct
          ...StandardProductType
          ...CustomProductType
          __typename
        }
        userErrors {
          field
          message
          __typename
        }
        __typename
      }
    }
    
    fragment PricingCardVariant on ProductVariant {
      id
      price
      compareAtPrice
      taxable
      taxCode
      presentmentPrices(first: 2) {
        edges {
          node {
            price {
              amount
              __typename
            }
            __typename
          }
          __typename
        }
        __typename
      }
      showUnitPrice
      unitPriceMeasurement {
        quantityValue
        quantityUnit
        referenceValue
        referenceUnit
        __typename
      }
      __typename
    }
    
    fragment SEOCardProduct on Product {
      seo {
        title
        description
        __typename
      }
      __typename
    }
    
    fragment StandardProductType on Product {
      standardProductType {
        productTaxonomyNodeId
        parentProductTaxonomyNodeId
        name
        fullName
        isLeaf
        isRoot
        __typename
      }
      inferredProductMetadata {
        standardProductType {
          productTaxonomyNodeId
          parentProductTaxonomyNodeId
          name
          fullName
          isLeaf
          isRoot
          __typename
        }
        __typename
      }
      __typename
    }
    
    fragment CustomProductType on Product {
      customProductType
      __typename
    }
    
    
    
    
    8、点击选择 variables,然后右键复制值。如图8
    点击选择 variables,然后右键复制值。
    图8
    9、粘贴至 Altair 的变量中。如图9
    粘贴至 Altair 的变量中。
    图9
    
    
    {
      "media": null,
      "product": {
        "standardProductType": null,
        "customProductType": null,
        "title": "标题 20220223 1",
        "descriptionHtml": "",
        "handle": "",
        "seo": {
          "title": "",
          "description": ""
        },
        "status": "DRAFT",
        "variants": [
          {
            "compareAtPrice": null,
            "price": "0",
            "taxable": true,
            "inventoryItem": {
              "cost": null,
              "countryCodeOfOrigin": null,
              "provinceCodeOfOrigin": null,
              "harmonizedSystemCode": null,
              "tracked": true
            },
            "requiresShipping": true,
            "weight": 0,
            "weightUnit": "KILOGRAMS",
            "fulfillmentServiceId": "gid://shopify/FulfillmentService/manual",
            "sku": "",
            "barcode": "",
            "inventoryPolicy": "DENY",
            "showUnitPrice": false,
            "unitPriceMeasurement": {
              "quantityValue": 0,
              "quantityUnit": null,
              "referenceValue": 0,
              "referenceUnit": null
            },
            "taxCode": null,
            "inventoryQuantities": [
              {
                "availableQuantity": 0,
                "locationId": "gid://shopify/Location/66268496078"
              }
            ],
            "options": [
              "Default Title"
            ]
          }
        ],
        "images": [],
        "tags": [],
        "templateSuffix": "",
        "giftCardTemplateSuffix": "",
        "vendor": "",
        "giftCard": false,
        "collectionsToJoin": [],
        "workflow": "product-details-create",
        "metafields": []
      }
    }
    
    
    
    10、发送请求报错,响应:Field ‘resourceAlerts’ doesn’t exist on type ‘Product’。在查询中依次删除:resourceAlerts、showUnitPrice、unitPriceMeasurement、standardProductType。如图10
    发送请求报错,响应:Field 'resourceAlerts' doesn't exist on type 'Product'。在查询中依次删除:resourceAlerts、showUnitPrice、unitPriceMeasurement、standardProductType。
    图10
    
    
    {
      "errors": [
        {
          "message": "Field 'resourceAlerts' doesn't exist on type 'Product'",
          "locations": [
            {
              "line": 8,
              "column": 7
            }
          ],
          "path": [
            "mutation CreateProduct",
            "productCreate",
            "product",
            "resourceAlerts"
          ],
          "extensions": {
            "code": "undefinedField",
            "typeName": "Product",
            "fieldName": "resourceAlerts"
          }
        },
        {
          "message": "Field 'showUnitPrice' doesn't exist on type 'ProductVariant'",
          "locations": [
            {
              "line": 88,
              "column": 3
            }
          ],
          "path": [
            "fragment PricingCardVariant",
            "showUnitPrice"
          ],
          "extensions": {
            "code": "undefinedField",
            "typeName": "ProductVariant",
            "fieldName": "showUnitPrice"
          }
        },
        {
          "message": "Field 'unitPriceMeasurement' doesn't exist on type 'ProductVariant'",
          "locations": [
            {
              "line": 89,
              "column": 3
            }
          ],
          "path": [
            "fragment PricingCardVariant",
            "unitPriceMeasurement"
          ],
          "extensions": {
            "code": "undefinedField",
            "typeName": "ProductVariant",
            "fieldName": "unitPriceMeasurement"
          }
        },
        {
          "message": "Field 'standardProductType' doesn't exist on type 'Product'",
          "locations": [
            {
              "line": 109,
              "column": 3
            }
          ],
          "path": [
            "fragment StandardProductType",
            "standardProductType"
          ],
          "extensions": {
            "code": "undefinedField",
            "typeName": "Product",
            "fieldName": "standardProductType"
          }
        },
        {
          "message": "Field 'inferredProductMetadata' doesn't exist on type 'Product'",
          "locations": [
            {
              "line": 118,
              "column": 3
            }
          ],
          "path": [
            "fragment StandardProductType",
            "inferredProductMetadata"
          ],
          "extensions": {
            "code": "undefinedField",
            "typeName": "Product",
            "fieldName": "inferredProductMetadata"
          }
        }
      ]
    }
    
    
    
    11、发送请求报错,响应:Variable $product of type ProductInput! was provided invalid value for standardProductType (Field is not defined on ProductInput), variants.0.inventoryItem.countryCodeOfOrigin (Field is not defined on InventoryItemInput), variants.0.inventoryItem.provinceCodeOfOrigin (Field is not defined on InventoryItemInput), variants.0.inventoryItem.harmonizedSystemCode (Field is not defined on InventoryItemInput), variants.0.showUnitPrice (Field is not defined on ProductVariantInput), variants.0.unitPriceMeasurement (Field is not defined on ProductVariantInput), workflow (Field is not defined on ProductInput)。在变量中依次删除:standardProductType、variants.0.inventoryItem.countryCodeOfOrigin、variants.0.inventoryItem.provinceCodeOfOrigin、variants.0.inventoryItem.harmonizedSystemCode、variants.0.showUnitPrice、variants.0.unitPriceMeasurement、workflow。如图11
    发送请求报错,响应:Variable $product of type ProductInput! was provided invalid value
    图11
    
    
    {
      "errors": [
        {
          "message": "Variable $product of type ProductInput! was provided invalid value for standardProductType (Field is not defined on ProductInput), variants.0.inventoryItem.countryCodeOfOrigin (Field is not defined on InventoryItemInput), variants.0.inventoryItem.provinceCodeOfOrigin (Field is not defined on InventoryItemInput), variants.0.inventoryItem.harmonizedSystemCode (Field is not defined on InventoryItemInput), variants.0.showUnitPrice (Field is not defined on ProductVariantInput), variants.0.unitPriceMeasurement (Field is not defined on ProductVariantInput), workflow (Field is not defined on ProductInput)",
          "locations": [
            {
              "line": 1,
              "column": 24
            }
          ],
          "extensions": {
            "value": {
              "standardProductType": null,
              "customProductType": null,
              "title": "标题 20220223 3",
              "descriptionHtml": "",
              "handle": "",
              "seo": {
                "title": "",
                "description": ""
              },
              "status": "DRAFT",
              "variants": [
                {
                  "compareAtPrice": null,
                  "price": "0",
                  "taxable": true,
                  "inventoryItem": {
                    "cost": null,
                    "countryCodeOfOrigin": null,
                    "provinceCodeOfOrigin": null,
                    "harmonizedSystemCode": null,
                    "tracked": true
                  },
                  "requiresShipping": true,
                  "weight": 0,
                  "weightUnit": "KILOGRAMS",
                  "fulfillmentServiceId": "gid://shopify/FulfillmentService/manual",
                  "sku": "",
                  "barcode": "",
                  "inventoryPolicy": "DENY",
                  "showUnitPrice": false,
                  "unitPriceMeasurement": {
                    "quantityValue": 0,
                    "quantityUnit": null,
                    "referenceValue": 0,
                    "referenceUnit": null
                  },
                  "taxCode": null,
                  "inventoryQuantities": [
                    {
                      "availableQuantity": 0,
                      "locationId": "gid://shopify/Location/66268496078"
                    }
                  ],
                  "options": [
                    "Default Title"
                  ]
                }
              ],
              "images": [],
              "tags": [],
              "templateSuffix": "",
              "giftCardTemplateSuffix": "",
              "vendor": "",
              "giftCard": false,
              "collectionsToJoin": [],
              "workflow": "product-details-create",
              "metafields": []
            },
            "problems": [
              {
                "path": [
                  "standardProductType"
                ],
                "explanation": "Field is not defined on ProductInput"
              },
              {
                "path": [
                  "variants",
                  0,
                  "inventoryItem",
                  "countryCodeOfOrigin"
                ],
                "explanation": "Field is not defined on InventoryItemInput"
              },
              {
                "path": [
                  "variants",
                  0,
                  "inventoryItem",
                  "provinceCodeOfOrigin"
                ],
                "explanation": "Field is not defined on InventoryItemInput"
              },
              {
                "path": [
                  "variants",
                  0,
                  "inventoryItem",
                  "harmonizedSystemCode"
                ],
                "explanation": "Field is not defined on InventoryItemInput"
              },
              {
                "path": [
                  "variants",
                  0,
                  "showUnitPrice"
                ],
                "explanation": "Field is not defined on ProductVariantInput"
              },
              {
                "path": [
                  "variants",
                  0,
                  "unitPriceMeasurement"
                ],
                "explanation": "Field is not defined on ProductVariantInput"
              },
              {
                "path": [
                  "workflow"
                ],
                "explanation": "Field is not defined on ProductInput"
              }
            ]
          }
        }
      ]
    }
    
    
    
    12、创建产品成功。响应 200。如图12
    创建产品成功。响应 200。
    图12
    请求查询:
    
    
    mutation CreateProduct($product: ProductInput!, $media: [CreateMediaInput!]) {
      productCreate(input: $product, media: $media) {
        product {
          id
          title
          handle
          descriptionHtml
          firstVariant: variants(first: 1) {
            edges {
              node {
                id
                requiresShipping
                weight
                weightUnit
                barcode
                sku
                inventoryPolicy
                fulfillmentService {
                  id
                  __typename
                }
                inventoryItem {
                  id
                  unitCost {
                    amount
                    __typename
                  }
                  countryCodeOfOrigin
                  provinceCodeOfOrigin
                  harmonizedSystemCode
                  tracked
                  __typename
                }
                ...PricingCardVariant
                __typename
              }
              __typename
            }
            __typename
          }
          ...SEOCardProduct
          ...CustomProductType
          __typename
        }
        userErrors {
          field
          message
          __typename
        }
        __typename
      }
    }
    
    fragment PricingCardVariant on ProductVariant {
      id
      price
      compareAtPrice
      taxable
      taxCode
      presentmentPrices(first: 2) {
        edges {
          node {
            price {
              amount
              __typename
            }
            __typename
          }
          __typename
        }
        __typename
      }
      __typename
    }
    
    fragment SEOCardProduct on Product {
      seo {
        title
        description
        __typename
      }
      __typename
    }
    
    fragment CustomProductType on Product {
      customProductType
      __typename
    }
    
    
    
    
    请求变量:
    
    
    {
      "media": null,
      "product": {
        "customProductType": null,
        "title": "标题 20220223 3",
        "descriptionHtml": "",
        "handle": "",
        "seo": {
          "title": "",
          "description": ""
        },
        "status": "DRAFT",
        "variants": [
          {
            "compareAtPrice": null,
            "price": "0",
            "taxable": true,
            "inventoryItem": {
              "cost": null,
              "tracked": true
            },
            "requiresShipping": true,
            "weight": 0,
            "weightUnit": "KILOGRAMS",
            "fulfillmentServiceId": "gid://shopify/FulfillmentService/manual",
            "sku": "",
            "barcode": "",
            "inventoryPolicy": "DENY",
            "taxCode": null,
            "inventoryQuantities": [
              {
                "availableQuantity": 0,
                "locationId": "gid://shopify/Location/66268496078"
              }
            ],
            "options": [
              "Default Title"
            ]
          }
        ],
        "images": [],
        "tags": [],
        "templateSuffix": "",
        "giftCardTemplateSuffix": "",
        "vendor": "",
        "giftCard": false,
        "collectionsToJoin": [],
        "metafields": []
      }
    }
    
    
    
    响应:
    
    
    {
      "data": {
        "productCreate": {
          "product": {
            "id": "gid://shopify/Product/6956647317710",
            "title": "标题 20220223 3",
            "handle": "标题-20220223-3",
            "descriptionHtml": "",
            "firstVariant": {
              "edges": [
                {
                  "node": {
                    "id": "gid://shopify/ProductVariant/40929372405966",
                    "requiresShipping": true,
                    "weight": 0,
                    "weightUnit": "KILOGRAMS",
                    "barcode": "",
                    "sku": "",
                    "inventoryPolicy": "DENY",
                    "fulfillmentService": {
                      "id": "gid://shopify/FulfillmentService/manual",
                      "__typename": "FulfillmentService"
                    },
                    "inventoryItem": {
                      "id": "gid://shopify/InventoryItem/43021592854734",
                      "unitCost": null,
                      "countryCodeOfOrigin": null,
                      "provinceCodeOfOrigin": null,
                      "harmonizedSystemCode": null,
                      "tracked": true,
                      "__typename": "InventoryItem"
                    },
                    "price": "0.00",
                    "compareAtPrice": null,
                    "taxable": true,
                    "taxCode": null,
                    "presentmentPrices": {
                      "edges": [
                        {
                          "node": {
                            "price": {
                              "amount": "0.0",
                              "__typename": "MoneyV2"
                            },
                            "__typename": "ProductVariantPricePair"
                          },
                          "__typename": "ProductVariantPricePairEdge"
                        }
                      ],
                      "__typename": "ProductVariantPricePairConnection"
                    },
                    "__typename": "ProductVariant"
                  },
                  "__typename": "ProductVariantEdge"
                }
              ],
              "__typename": "ProductVariantConnection"
            },
            "seo": {
              "title": null,
              "description": null,
              "__typename": "SEO"
            },
            "__typename": "Product",
            "customProductType": null
          },
          "userErrors": [],
          "__typename": "ProductCreatePayload"
        }
      },
      "extensions": {
        "cost": {
          "requestedQueryCost": 20,
          "actualQueryCost": 19,
          "throttleStatus": {
            "maximumAvailable": 1000,
            "currentlyAvailable": 981,
            "restoreRate": 50
          }
        }
      }
    }
    
    
    
    13、为何 Shopify 后台调用 GraphQL API 的请求参数与最新版本的 GraphQL API 不相匹配,初步怀疑可能是版本不一致所导致。Shopify 后台调用 GraphQL API 的版本不是最新版本。现在最新版本为:2022-01。而后台调用的版本为:2020-07。如图13
    为何 Shopify 后台调用 GraphQL API 的请求参数与最新版本的 GraphQL API 不相匹配,初步怀疑可能是版本不一致所导致。Shopify 后台调用 GraphQL API 的版本不是最新版本。现在最新版本为:2022-01。而后台调用的版本为:2020-07。
    图13
    14、当请求响应报错时的结构。如图14
    当请求响应报错时的结构。
    图14
    
    
    mutation {
      onlineStoreThemeAssetCreate(
        input: { themeId: "vogue", content: "string", key: "string" }
      ) {
        themeAsset {
          id
          themeId
          version
          content
          key
          mimeType
          category
          schema
          createdAt
          updatedAt
          deletable
          renameable
          updatable
        }
      }
    }
    
    
    
    
    
    {
      "errors": [
        {
          "debugMessage": "Undefined index: key",
          "message": "Internal server error",
          "extensions": {
            "category": "internal"
          },
          "locations": [
            {
              "line": 5,
              "column": 5
            }
          ],
          "path": [
            "onlineStoreThemeAssetCreate",
            "themeAsset"
          ],
          "trace": [
            {
              "file": "E:\\wwwroot\\object\\Modules\\ThemeStore\\Resolver\\OnlineStoreTheme\\ThemeAssetResolver.php",
              "line": 15,
              "call": "Illuminate\\Foundation\\Bootstrap\\HandleExceptions::handleError(8, 'Undefined index: key', 'E:\\wwwroot\\object\\Modules\\ThemeStore\\Resolver\\OnlineStoreTheme\\ThemeAssetResolver.php', 15, array(5))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\FieldDirective.php",
              "line": 52,
              "call": "Modules\\ThemeStore\\Resolver\\OnlineStoreTheme\\ThemeAssetResolver::__invoke(array(1), array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\RenameArgsDirective.php",
              "line": 33,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\FieldDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\SpreadDirective.php",
              "line": 36,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\RenameArgsDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\ArgTraversalDirective.php",
              "line": 29,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\SpreadDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Validation\\ValidateDirective.php",
              "line": 53,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\ArgTraversalDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\ArgTraversalDirective.php",
              "line": 29,
              "call": "Nuwave\\Lighthouse\\Validation\\ValidateDirective::Nuwave\\Lighthouse\\Validation\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\TrimDirective.php",
              "line": 56,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\ArgTraversalDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Factories\\FieldFactory.php",
              "line": 99,
              "call": "Nuwave\\Lighthouse\\Schema\\Directives\\TrimDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 623,
              "call": "Nuwave\\Lighthouse\\Schema\\Factories\\FieldFactory::Nuwave\\Lighthouse\\Schema\\Factories\\{closure}(array(1), array(0), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 550,
              "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, instance of Closure, array(1), instance of GraphQL\\Type\\Definition\\ResolveInfo)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 1195,
              "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: OnlineStoreThemeAssetCreatePayload, array(1), instance of ArrayObject(1), array(2))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 1145,
              "call": "GraphQL\\Executor\\ReferenceExecutor::executeFields(GraphQLType: OnlineStoreThemeAssetCreatePayload, array(1), array(1), instance of ArrayObject(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 1106,
              "call": "GraphQL\\Executor\\ReferenceExecutor::collectAndExecuteSubfields(GraphQLType: OnlineStoreThemeAssetCreatePayload, instance of ArrayObject(1), array(1), array(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 793,
              "call": "GraphQL\\Executor\\ReferenceExecutor::completeObjectValue(GraphQLType: OnlineStoreThemeAssetCreatePayload, instance of ArrayObject(1), instance of GraphQL\\Type\\Definition\\ResolveInfo, array(1), array(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 654,
              "call": "GraphQL\\Executor\\ReferenceExecutor::completeValue(GraphQLType: OnlineStoreThemeAssetCreatePayload, instance of ArrayObject(1), instance of GraphQL\\Type\\Definition\\ResolveInfo, array(1), array(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 557,
              "call": "GraphQL\\Executor\\ReferenceExecutor::completeValueCatchingError(GraphQLType: OnlineStoreThemeAssetCreatePayload, instance of ArrayObject(1), instance of GraphQL\\Type\\Definition\\ResolveInfo, array(1), array(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 474,
              "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: Mutation, null, instance of ArrayObject(1), array(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 857,
              "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeAssetCreate')"
            },
            {
              "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeAssetCreate')"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 859,
              "function": "array_reduce(array(1), instance of Closure, array(0))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 490,
              "call": "GraphQL\\Executor\\ReferenceExecutor::promiseReduce(array(1), instance of Closure, array(0))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 263,
              "call": "GraphQL\\Executor\\ReferenceExecutor::executeFieldsSerially(GraphQLType: Mutation, null, array(0), instance of ArrayObject(1))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
              "line": 215,
              "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\Executor.php",
              "line": 156,
              "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
              "line": 162,
              "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
              "line": 94,
              "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 268,
              "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 203,
              "call": "Nuwave\\Lighthouse\\GraphQL::executeParsedQuery(instance of GraphQL\\Language\\AST\\DocumentNode, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 162,
              "call": "Nuwave\\Lighthouse\\GraphQL::parseAndExecuteQuery('mutation {\n  onlineStoreThemeAssetCreate(\n    input: { themeId: \"vogue\", content: \"string\", key: \"string\" }\n  ) {\n    themeAsset {\n      id\n      themeId\n      version\n      content\n      key\n      mimeType\n      category\n      schema\n      createdAt\n      updatedAt\n      deletable\n      renameable\n      updatable\n    }\n  }\n}', instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 121,
              "call": "Nuwave\\Lighthouse\\GraphQL::executeOperation(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Utils.php",
              "line": 99,
              "call": "Nuwave\\Lighthouse\\GraphQL::Nuwave\\Lighthouse\\{closure}(instance of GraphQL\\Server\\OperationParams)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
              "line": 120,
              "call": "Nuwave\\Lighthouse\\Support\\Utils::applyEach(instance of Closure, instance of GraphQL\\Server\\OperationParams)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Controllers\\GraphQLController.php",
              "line": 32,
              "call": "Nuwave\\Lighthouse\\GraphQL::executeOperationOrOperations(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php",
              "line": 48,
              "call": "Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController::__invoke(instance of Illuminate\\Http\\Request, instance of Nuwave\\Lighthouse\\GraphQL, instance of Illuminate\\Events\\Dispatcher, instance of Laragraph\\Utils\\RequestParser, instance of Nuwave\\Lighthouse\\Execution\\SingleResponse, instance of Nuwave\\Lighthouse\\Execution\\ContextFactory)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
              "line": 219,
              "call": "Illuminate\\Routing\\ControllerDispatcher::dispatch(instance of Illuminate\\Routing\\Route, instance of Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController, '__invoke')"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
              "line": 176,
              "call": "Illuminate\\Routing\\Route::runController()"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 681,
              "call": "Illuminate\\Routing\\Route::run()"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 130,
              "call": "Illuminate\\Routing\\Router::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AttemptAuthentication.php",
              "line": 34,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AttemptAuthentication::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AcceptJson.php",
              "line": 27,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AcceptJson::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 105,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 683,
              "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 658,
              "call": "Illuminate\\Routing\\Router::runRouteWithinStack(instance of Illuminate\\Routing\\Route, instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 624,
              "call": "Illuminate\\Routing\\Router::runRoute(instance of Illuminate\\Http\\Request, instance of Illuminate\\Routing\\Route)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
              "line": 613,
              "call": "Illuminate\\Routing\\Router::dispatchToRoute(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
              "line": 170,
              "call": "Illuminate\\Routing\\Router::dispatch(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 130,
              "call": "Illuminate\\Foundation\\Http\\Kernel::Illuminate\\Foundation\\Http\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\barryvdh\\laravel-debugbar\\src\\Middleware\\InjectDebugbar.php",
              "line": 67,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Barryvdh\\Debugbar\\Middleware\\InjectDebugbar::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\app\\Http\\Middleware\\ChangeAppUrlMiddleware.php",
              "line": 23,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "App\\Http\\Middleware\\ChangeAppUrlMiddleware::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
              "line": 21,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
              "line": 21,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
              "line": 27,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php",
              "line": 63,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
              "line": 57,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Fideloper\\Proxy\\TrustProxies::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\dingo\\api\\src\\Http\\Middleware\\Request.php",
              "line": 111,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 171,
              "call": "Dingo\\Api\\Http\\Middleware\\Request::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
              "line": 105,
              "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
              "line": 145,
              "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
            },
            {
              "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
              "line": 110,
              "call": "Illuminate\\Foundation\\Http\\Kernel::sendRequestThroughRouter(instance of Illuminate\\Http\\Request)"
            },
            {
              "file": "E:\\wwwroot\\object\\public\\index.php",
              "line": 57,
              "call": "Illuminate\\Foundation\\Http\\Kernel::handle(instance of Illuminate\\Http\\Request)"
            }
          ]
        }
      ],
      "data": {
        "onlineStoreThemeAssetCreate": {
          "themeAsset": null
        }
      }
    }
    
    
    
    15、当请求响应成功时的结构。如图15
    当请求响应成功时的结构。
    图15
    
    
    
    mutation {
      onlineStoreThemeAssetCreate(
        input: { themeId: "vogue", content: "string", key: "string" }
      ) {
        themeAsset {
          id
          themeId
          content
          key
          mimeType
          category
          schema
          createdAt
          updatedAt
          deletable
          renameable
          updatable
        }
      }
    }
    
    
    
    
    
    
    {
      "data": {
        "onlineStoreThemeAssetCreate": {
          "themeAsset": {
            "id": "653",
            "themeId": "vogue",
            "content": "string",
            "key": "string",
            "mimeType": "text/x-php",
            "category": "unknown",
            "schema": null,
            "createdAt": "2022-02-25 01:49:53",
            "updatedAt": "2022-02-25 01:49:53",
            "deletable": false,
            "renameable": false,
            "updatable": false
          }
        }
      }
    }
    
    
    
  • 删除 GitHub 中的仓库的流程

    删除 GitHub 中的仓库的流程

    1、删除 GitHub 中的仓库。由于公司安全方面的要求,一些代码不允许放在 GitHub 中。最终决定删除掉。如图1

    删除 GitHub 中的仓库。由于公司安全方面的要求,一些代码不允许放在 GitHub 中。最终决定删除掉。
    图1

    2、打开网址:https://github.com/shuijingwan/weibo ,决定删除掉此仓库。进入 Settings 页面。如图2

    打开网址:https://github.com/shuijingwan/weibo ,决定删除掉此仓库。进入 Settings 页面
    图2

    3、滚动至页面尾部,Danger Zone – Delete this repository 。如图3

    滚动至页面尾部,Danger Zone - Delete this repository
    图3

    4、弹出确认对话框,此操作无法撤消。这将永久删除 shuijingwan/weibo 存储库、wiki、问题、评论、包、机密、工作流运行,并删除所有协作者关联。请输入 shuijingwan/weibo 确认。如图4

    弹出确认对话框,此操作无法撤消。这将永久删除 shuijingwan/weibo 存储库、wiki、问题、评论、包、机密、工作流运行,并删除所有协作者关联。请输入 shuijingwan/weibo 确认。
    图4

    5、跳转至 Confirm access 页面,提示:您正在进入 sudo 模式。需要输入登录密码。如图5

    跳转至 Confirm access 页面,提示:您正在进入 sudo 模式。需要输入登录密码。
    图5

    6、Your repository “shuijingwan/weibo” was successfully deleted.。删除成功。如图6

    Your repository "shuijingwan/weibo" was successfully deleted.。删除成功。
    图6

  • 从 REST 迁移到 GraphQL 的一些思考与实践(响应嵌套的列表结构),参考 Shopify

    从 REST 迁移到 GraphQL 的一些思考与实践(响应嵌套的列表结构),参考 Shopify

    1、参考:从 REST 迁移到 GraphQL 的一些思考与实践,参考 GitHub。在左侧为模板文件的顶级目录结构。针对每一个顶级目录,需要设置其是否允许新增文件。如图1
    参考:从 REST 迁移到 GraphQL 的一些思考与实践,参考 GitHub。在左侧为模板文件的顶级目录结构。针对每一个顶级目录,需要设置其是否允许新增文件。
    图1
    2、本计划借鉴 Shopify 的 GraphQL 的响应结构,但是其是直接响应 html 的结构,并未使用 GraphQL。如图2
    本计划借鉴 Shopify 的 GraphQL 的响应结构,但是其是直接响应 html 的结构,并未使用 GraphQL
    图2
    3、借鉴 Shopify 的 GraphQL 的 products,其中每一个产品皆具有其自身的 图片列表。如图3
    借鉴 Shopify 的 GraphQL 的 products,其中每一个产品皆具有其自身的 图片列表
    图3
    
    
    {
      products(first: 3) {
        edges {
          node {
            id
            title
            images(first: 3) {
              edges {
                node {
                  id
                  width
                }
              }
            }
          }
        }
      }
    }
    
    
    
    
    
    {
      "data": {
        "products": {
          "edges": [
            {
              "node": {
                "id": "gid://shopify/Product/6944715342030",
                "title": "commercial kitchen quality",
                "images": {
                  "edges": [
                    {
                      "node": {
                        "id": "gid://shopify/ProductImage/30455717036238",
                        "width": 1920
                      }
                    },
                    {
                      "node": {
                        "id": "gid://shopify/ProductImage/30455718838478",
                        "width": 1920
                      }
                    }
                  ]
                }
              }
            },
            {
              "node": {
                "id": "gid://shopify/Product/6944715636942",
                "title": "Easter Photographing Dress-up Acessories",
                "images": {
                  "edges": []
                }
              }
            },
            {
              "node": {
                "id": "gid://shopify/Product/6944715702478",
                "title": "Perfect Pet Hair Remover",
                "images": {
                  "edges": []
                }
              }
            }
          ]
        }
      },
      "extensions": {
        "cost": {
          "requestedQueryCost": 20,
          "actualQueryCost": 13,
          "throttleStatus": {
            "maximumAvailable": 1000,
            "currentlyAvailable": 987,
            "restoreRate": 50
          }
        }
      }
    }
    
    
    
    4、Shopify 的 products 相当于模板文件的顶级目录列表。而 每一个产品皆具有其自身的 图片列表,相当于 每一个顶级目录皆具有其自身的 模板文件列表。最终实现了类似的响应结构。如图4
    Shopify 的 products 相当于模板文件的顶级目录列表。而 每一个产品皆具有其自身的 图片列表,相当于 每一个顶级目录皆具有其自身的 模板文件列表。最终实现了类似的响应结构
    图4
    
    
    query{
      onlineStoreTheme(themeId: "vogue"){
        ...____
      }
    }
    
    fragment ____ on OnlineStoreTheme {
      themeFirstLevelAssets {
        name
        creatable
        themeAssets {
          id
          key
        }
      }
    }
    
    
    
    
    
    
    {
      "data": {
        "onlineStoreTheme": {
          "themeFirstLevelAssets": [
            {
              "name": "Assets",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "1",
                  "key": "assets/iconfont/iconfont.css"
                },
                {
                  "id": "2",
                  "key": "assets/iconfont/iconfont.js"
                },
                {
                  "id": "3",
                  "key": "assets/iconfont/iconfont.json"
                },
                {
                  "id": "4",
                  "key": "assets/iconfont/iconfont.woff2"
                }
              ]
            },
            {
              "name": "Auth",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "5",
                  "key": "auth/login.blade.php"
                },
                {
                  "id": "6",
                  "key": "auth/register.blade.php"
                }
              ]
            },
            {
              "name": "Components",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "7",
                  "key": "components/carousel.blade.php"
                },
                {
                  "id": "8",
                  "key": "components/collections.blade.php"
                },
                {
                  "id": "9",
                  "key": "components/combinationRecommendation.blade.php"
                },
                {
                  "id": "10",
                  "key": "components/css.blade.php"
                },
                {
                  "id": "11",
                  "key": "components/foot.blade.php"
                },
                {
                  "id": "12",
                  "key": "components/footInfo.blade.php"
                },
                {
                  "id": "13",
                  "key": "components/footMenu.blade.php"
                },
                {
                  "id": "14",
                  "key": "components/footSubscribe.blade.php"
                },
                {
                  "id": "15",
                  "key": "components/footTextImg.blade.php"
                },
                {
                  "id": "16",
                  "key": "components/header.blade.php"
                },
                {
                  "id": "17",
                  "key": "components/hotSales.blade.php"
                },
                {
                  "id": "18",
                  "key": "components/image.blade.php"
                },
                {
                  "id": "19",
                  "key": "components/imageText.blade.php"
                },
                {
                  "id": "20",
                  "key": "components/megaMenu.blade.php"
                },
                {
                  "id": "21",
                  "key": "components/menuCollapsible.blade.php"
                },
                {
                  "id": "22",
                  "key": "components/publicity.blade.php"
                },
                {
                  "id": "23",
                  "key": "components/singlecommodity.blade.php"
                },
                {
                  "id": "24",
                  "key": "components/text.blade.php"
                },
                {
                  "id": "25",
                  "key": "components/video.blade.php"
                }
              ]
            },
            {
              "name": "Config",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "26",
                  "key": "config/settings_data.json"
                },
                {
                  "id": "27",
                  "key": "config/settings_schema.json"
                }
              ]
            },
            {
              "name": "Js",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "28",
                  "key": "js/address.js"
                },
                {
                  "id": "29",
                  "key": "js/app.js"
                },
                {
                  "id": "30",
                  "key": "js/cart.js"
                },
                {
                  "id": "31",
                  "key": "js/collectionItem.js"
                },
                {
                  "id": "32",
                  "key": "js/collections.js"
                },
                {
                  "id": "33",
                  "key": "js/common/banner.vue"
                },
                {
                  "id": "34",
                  "key": "js/common/cartFreeSpTips.vue"
                },
                {
                  "id": "35",
                  "key": "js/common/navbar.vue"
                },
                {
                  "id": "36",
                  "key": "js/common/sortselector.vue"
                },
                {
                  "id": "37",
                  "key": "js/custom.js"
                },
                {
                  "id": "38",
                  "key": "js/error404.js"
                },
                {
                  "id": "39",
                  "key": "js/home.js"
                },
                {
                  "id": "40",
                  "key": "js/index.js"
                },
                {
                  "id": "41",
                  "key": "js/login.js"
                },
                {
                  "id": "42",
                  "key": "js/order.js"
                },
                {
                  "id": "43",
                  "key": "js/page.js"
                },
                {
                  "id": "44",
                  "key": "js/productDetail.js"
                },
                {
                  "id": "45",
                  "key": "js/register.js"
                },
                {
                  "id": "46",
                  "key": "js/search.js"
                },
                {
                  "id": "47",
                  "key": "js/view/account/accountbodyaddress.vue"
                },
                {
                  "id": "48",
                  "key": "js/view/account/accountbodyorder.vue"
                },
                {
                  "id": "49",
                  "key": "js/view/account/accounttop.vue"
                },
                {
                  "id": "50",
                  "key": "js/view/account/addressfrom.vue"
                },
                {
                  "id": "51",
                  "key": "js/view/account/index.vue"
                },
                {
                  "id": "52",
                  "key": "js/view/cart/index.vue"
                },
                {
                  "id": "53",
                  "key": "js/view/collections/card.vue"
                },
                {
                  "id": "54",
                  "key": "js/view/collections/index.vue"
                },
                {
                  "id": "55",
                  "key": "js/view/product/descriptabs.vue"
                },
                {
                  "id": "56",
                  "key": "js/view/product/index.vue"
                },
                {
                  "id": "57",
                  "key": "js/view/product/MediaFlat.vue"
                },
                {
                  "id": "58",
                  "key": "js/view/product/MediaLeft.vue"
                },
                {
                  "id": "59",
                  "key": "js/view/product/scrollSlideVertical.vue"
                },
                {
                  "id": "60",
                  "key": "js/view/product/slideVertical.vue"
                },
                {
                  "id": "61",
                  "key": "js/view/productlist/index.vue"
                },
                {
                  "id": "62",
                  "key": "js/view/search/index.vue"
                }
              ]
            },
            {
              "name": "Layouts",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "63",
                  "key": "layouts/basic.blade.php"
                }
              ]
            },
            {
              "name": "Pages",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "64",
                  "key": "pages/address.blade.php"
                },
                {
                  "id": "65",
                  "key": "pages/cart.blade.php"
                },
                {
                  "id": "66",
                  "key": "pages/collections.blade.php"
                },
                {
                  "id": "67",
                  "key": "pages/collectiontitem.blade.php"
                },
                {
                  "id": "68",
                  "key": "pages/custom.blade.php"
                },
                {
                  "id": "69",
                  "key": "pages/home.blade.php"
                },
                {
                  "id": "70",
                  "key": "pages/index.blade.php"
                },
                {
                  "id": "71",
                  "key": "pages/order.blade.php"
                },
                {
                  "id": "72",
                  "key": "pages/product_detail.blade.php"
                },
                {
                  "id": "73",
                  "key": "pages/search.blade.php"
                }
              ]
            },
            {
              "name": "Sass",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "74",
                  "key": "sass/app.scss"
                },
                {
                  "id": "75",
                  "key": "sass/applications.scss"
                },
                {
                  "id": "76",
                  "key": "sass/banner.scss"
                },
                {
                  "id": "77",
                  "key": "sass/collectionItems.scss"
                },
                {
                  "id": "78",
                  "key": "sass/collections.scss"
                },
                {
                  "id": "79",
                  "key": "sass/components.scss"
                },
                {
                  "id": "80",
                  "key": "sass/fonts.scss"
                },
                {
                  "id": "81",
                  "key": "sass/foot.scss"
                },
                {
                  "id": "82",
                  "key": "sass/global.scss"
                },
                {
                  "id": "83",
                  "key": "sass/header.scss"
                },
                {
                  "id": "84",
                  "key": "sass/hotsales.scss"
                },
                {
                  "id": "85",
                  "key": "sass/imagetext.scss"
                },
                {
                  "id": "86",
                  "key": "sass/index.scss"
                },
                {
                  "id": "87",
                  "key": "sass/pages.scss"
                },
                {
                  "id": "88",
                  "key": "sass/productDetail.scss"
                },
                {
                  "id": "89",
                  "key": "sass/publicity.scss"
                },
                {
                  "id": "90",
                  "key": "sass/text.scss"
                },
                {
                  "id": "91",
                  "key": "sass/video.scss"
                }
              ]
            },
            {
              "name": "Theme.json",
              "creatable": false,
              "themeAssets": [
                {
                  "id": "92",
                  "key": "theme.json"
                }
              ]
            }
          ]
        }
      }
    }
    
    
    
    5、由于模板文件列表,仅需要 key 字段。最后调整后的响应结构。如图5
    由于模板文件列表,仅需要 key 字段。最后调整后的响应结构
    图5
    
    
    query{
      onlineStoreTheme(themeId: "vogue"){
        ... ____
      }
    }
    
    fragment ____ on OnlineStoreTheme {
      themeAssetList {
        themeId
        name
        key
        creatable
        themeAssetKeys
      }
    }
    
    
    
    
    
    
    {
      "data": {
        "onlineStoreTheme": {
          "themeAssetList": [
            {
              "themeId": "vogue",
              "name": "Assets",
              "key": "assets",
              "creatable": false,
              "themeAssetKeys": [
                "assets/iconfont/iconfont.css",
                "assets/iconfont/iconfont.js",
                "assets/iconfont/iconfont.json",
                "assets/iconfont/iconfont.woff2"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Auth",
              "key": "auth",
              "creatable": false,
              "themeAssetKeys": [
                "auth/login.blade.php",
                "auth/register.blade.php"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Components",
              "key": "components",
              "creatable": false,
              "themeAssetKeys": [
                "components/carousel.blade.php",
                "components/collections.blade.php",
                "components/combinationRecommendation.blade.php",
                "components/css.blade.php",
                "components/foot.blade.php",
                "components/footInfo.blade.php",
                "components/footMenu.blade.php",
                "components/footSubscribe.blade.php",
                "components/footTextImg.blade.php",
                "components/header.blade.php",
                "components/hotSales.blade.php",
                "components/image.blade.php",
                "components/imageText.blade.php",
                "components/megaMenu.blade.php",
                "components/menuCollapsible.blade.php",
                "components/publicity.blade.php",
                "components/singlecommodity.blade.php",
                "components/text.blade.php",
                "components/video.blade.php"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Config",
              "key": "config",
              "creatable": false,
              "themeAssetKeys": [
                "config/settings_data.json",
                "config/settings_schema.json"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Js",
              "key": "js",
              "creatable": false,
              "themeAssetKeys": [
                "js/address.js",
                "js/app.js",
                "js/cart.js",
                "js/collectionItem.js",
                "js/collections.js",
                "js/common/banner.vue",
                "js/common/cartFreeSpTips.vue",
                "js/common/navbar.vue",
                "js/common/sortselector.vue",
                "js/custom.js",
                "js/error404.js",
                "js/home.js",
                "js/index.js",
                "js/login.js",
                "js/order.js",
                "js/page.js",
                "js/productDetail.js",
                "js/register.js",
                "js/search.js",
                "js/view/account/accountbodyaddress.vue",
                "js/view/account/accountbodyorder.vue",
                "js/view/account/accounttop.vue",
                "js/view/account/addressfrom.vue",
                "js/view/account/index.vue",
                "js/view/cart/index.vue",
                "js/view/collections/card.vue",
                "js/view/collections/index.vue",
                "js/view/product/descriptabs.vue",
                "js/view/product/index.vue",
                "js/view/product/MediaFlat.vue",
                "js/view/product/MediaLeft.vue",
                "js/view/product/scrollSlideVertical.vue",
                "js/view/product/slideVertical.vue",
                "js/view/productlist/index.vue",
                "js/view/search/index.vue"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Layouts",
              "key": "layouts",
              "creatable": false,
              "themeAssetKeys": [
                "layouts/basic.blade.php"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Pages",
              "key": "pages",
              "creatable": false,
              "themeAssetKeys": [
                "pages/address.blade.php",
                "pages/cart.blade.php",
                "pages/collections.blade.php",
                "pages/collectiontitem.blade.php",
                "pages/custom.blade.php",
                "pages/home.blade.php",
                "pages/index.blade.php",
                "pages/order.blade.php",
                "pages/product_detail.blade.php",
                "pages/search.blade.php"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Sass",
              "key": "sass",
              "creatable": false,
              "themeAssetKeys": [
                "sass/app.scss",
                "sass/applications.scss",
                "sass/banner.scss",
                "sass/collectionItems.scss",
                "sass/collections.scss",
                "sass/components.scss",
                "sass/fonts.scss",
                "sass/foot.scss",
                "sass/global.scss",
                "sass/header.scss",
                "sass/hotsales.scss",
                "sass/imagetext.scss",
                "sass/index.scss",
                "sass/pages.scss",
                "sass/productDetail.scss",
                "sass/publicity.scss",
                "sass/text.scss",
                "sass/video.scss"
              ]
            },
            {
              "themeId": "vogue",
              "name": "Theme.json",
              "key": "theme.json",
              "creatable": false,
              "themeAssetKeys": [
                "theme.json"
              ]
            }
          ]
        }
      }
    }
    
    
    
     
  • 在 MySQL 5.7 中搜索反斜杠(\),对于 Like 时的转义,需要使用 \\\\

    在 MySQL 5.7 中搜索反斜杠(\),对于 Like 时的转义,需要使用 \\\\

    1、表中数据如下
    
    
    INSERT INTO `object_store`.`theme_asset`(`id`, `theme_id`, `version`, `asset_key`, `mime_type`, `category`, `schema`, `created_at`, `updated_at`) VALUES (63, 'vogue', '', 'layouts\\basic.blade.php', 'text/html', 'unknown', NULL, '2022-02-15 09:59:41', '2022-02-15 09:59:41');
    
    
    
    
    2、当在执行 where like 查询时,使用 like ‘layouts\\%’ 试图查询出以 layouts\ 开头的数据行。结果为空。如图1
    当在执行 where like 查询时,使用 like 'layouts\\%' 试图查询出以 layouts\ 开头的数据行。结果为空。
    图1
    
    
    select
      `id`,
      `theme_id`,
      `version`,
      `asset_key`,
      `mime_type`,
      `category`,
      `schema`,
      `created_at`,
      `updated_at`
    from
      `theme_asset`
    where
      (
        `theme_id` = 'vogue'
        and `asset_key` like 'layouts\\%'
      )
    
    
    
    3、当在执行 where like 查询时,使用 like ‘layouts\\\\%’ 试图查询出以 layouts\ 开头的数据行。才真正搜索出相应的结果。如图2
    当在执行 where like 查询时,使用 like 'layouts\\\\%' 试图查询出以 layouts\ 开头的数据行。才真正搜索出相应的结果
    图2
    
    
    select
      `id`,
      `theme_id`,
      `version`,
      `asset_key`,
      `mime_type`,
      `category`,
      `schema`,
      `created_at`,
      `updated_at`
    from
      `theme_asset`
    where
      (
        `theme_id` = 'vogue'
        and `asset_key` like 'layouts\\%'
      )
    
    
    
    4、参考:https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html 。MySQL 在字符串中使用 C 转义语法(例如,\n 表示换行符)。如果您希望 LIKE 字符串包含文字 \,则必须将其加倍。(除非启用了 NO_BACKSLASH_ESCAPES SQL 模式,在这种情况下不使用转义字符。)例如,要搜索 \n,请将其指定为 \\n。 要搜索 \,请将其指定为 \\\\; 这是因为反斜杠被解析器剥离一次,并且在进行模式匹配时再次剥离,留下一个反斜杠进行匹配。如图3
    参考:https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html 。MySQL 在字符串中使用 C 转义语法(例如,\n 表示换行符)。如果您希望 LIKE 字符串包含文字 \,则必须将其加倍。(除非启用了 NO_BACKSLASH_ESCAPES SQL 模式,在这种情况下不使用转义字符。)例如,要搜索 \n,请将其指定为 \\n。 要搜索 \,请将其指定为 \\\\; 这是因为反斜杠被解析器剥离一次,并且在进行模式匹配时再次剥离,留下一个反斜杠进行匹配。
    图3
  • 在 Laravel Telescope 中,页面一直处于 Scanning…

    在 Laravel Telescope 中,页面一直处于 Scanning…

    1、在 Laravel Telescope 中,页面一直处于 Scanning…。查看网络,Table ‘object_store.telescope_entries’ doesn’t exist。如图1
    在 Laravel Telescope 中,页面一直处于 Scanning...。查看网络,Table 'object_store.telescope_entries' doesn't exist
    图1
    2、运行 migrate 命令:
    
    
    PS E:\wwwroot\object> php artisan migrate
    Migrating: 2018_08_08_100000_create_telescope_entries_table
    Migrated:  2018_08_08_100000_create_telescope_entries_table (0.49 seconds)
    
    
    
    3、刷新页面,响应 200。如图2
    刷新页面,响应 200
    图2