> For the complete documentation index, see [llms.txt](https://espier.gitbook.io/espier/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://espier.gitbook.io/espier/kuang-jia/intro/qing-qiu/controller.md).

# 控制器

控制器都放在 Http 目录，与 [路由](/espier/kuang-jia/intro/qing-qiu/route.md) 相对应，控制器也按照终端进行了分组：

* Admin
* Api
* Frontapi
* Shopapi
* Super
* Thirdparty

每个分组下的目录结构如下：

* Api
  * V1
    * Action   控制器实际所在目录&#x20;
    * Swagger  Swagger定义目录

## 定义控制器

下面是一个基础控制器类的例子。需要注意的是，该控制器继承了 Laravel 的基类控制器。该基类控制器提供了一些便利的方法，比如 middleware 方法，该方法可以为控制器行为添加中间件：

```
namespace AftersalesBundle\Http\Api\V1\Action;

use EspierBundle\Jobs\ExportFileJob;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;

use AftersalesBundle\Services\AftersalesService;

use Dingo\Api\Exception\ResourceException;

use EspierBundle\Traits\GetExportServiceTraits;

class Aftersales extends Controller
{
    use GetExportServiceTraits;

    public function getAftersalesDetail($aftersales_bn)
    {
        $companyId = app('auth')->user()->get('company_id');
        $aftersalesService = new AftersalesService();
        $result = $aftersalesService->getAftersalesInfo($companyId, $aftersales_bn);

        return $this->response->array($result);
    }
}
```

## 定义 API 文档

在 EcshopX 中每一个控制器方法都是一个 api都是一个接口，接口的出参和入参都是通过 注释来定义的，采用Swagger格式来定义。

控制器分组下的每一个版本都是一组 API ，定义一组 api 需要两步，以 AftersalesBundle 举例如下：

### 1、在 Swagger 目录下定义分组信息

定义 API 基本信息

```php
//AftersalesBundle/Http/Api/V1/Swagger/Info.php
<?php
/**
 * @SWG\Swagger(
 *     schemes={"http"},
 *     host="localhost",
 *     basePath="/api",
 *     @SWG\Info(
 *         version="1.0",
 *         title="售后单商家端调用接口",
 *         description="售后单",
 *     ),
 *     produces={"application/json"},
 * )
 */
```

定义 API Tag

```php
//AftersalesBundle/Http/Api/V1/Swagger/Tags.php
<?php
/**
 * @SWG\Tag(
 *   name="aftersales",
 *   description="售后单",
 * )
 */
```

根据需求定义接口所需数据对象：

```php
//AftersalesBundle/Http/Api/V1/Swagger/AftersalesErrorRespones.php

<?php
namespace AftersalesBundle\Http\Api\V1\Swagger;

/**
 * @SWG\Definition(type="object")
 */
class AftersalesErrorRespones
{
    /**
     * @SWG\Property
     * @var string
     */
    public $message;

    /**
     * @SWG\Property
     * @var string
     */
    public $errors;

    /**
     * @SWG\Property(format="int32")
     * @var int
     */
    public $code;

    /**
     * @SWG\Property(format="int32")
     * @var int
     */
    public $status_code;

    /**
     * @SWG\Property
     * @var string
     */
    public $debug;
}
```

### 2、在 Action 目录中的控制器的方法定义接口

```php
/**
     * @SWG\Get(
     *     path="/aftersales/{$aftersales_bn}",
     *     summary="获取售后单详情",
     *     tags={"aftersales"},
     *     description="获取售后单详情",
     *     operationId="getAftersalesDetail",
     *     @SWG\Parameter(
     *         name="Authorization",
     *         in="header",
     *         description="JWT验证token",
     *         required=true,
     *         type="string",
     *     ),
     *     @SWG\Parameter(
     *         name="aftersales_bn",
     *         in="path",
     *         description="售后单号",
     *         required=true,
     *         type="integer",
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="成功返回结构",
     *     ),
     *     @SWG\Response( response="default", description="错误返回结构", @SWG\Schema( type="array", @SWG\Items(ref="#/definitions/AftersalesErrorRespones") ) )
     * )
     */
    public function getAftersalesDetail($aftersales_bn)
    {
        $companyId = app('auth')->user()->get('company_id');
        $aftersalesService = new AftersalesService();
        $result = $aftersalesService->getAftersalesInfo($companyId, $aftersales_bn);

        return $this->response->array($result);
    }
```

Swagger 定义参数详见 [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#dataTypeType)

## 接口文档生成和接口测试

在通过 Swagger 注释的方式定义好接口文档后，可以通过本地开发环境查看和测试接口。

### 一、将 Swagger UI的资源拷贝到public目录中

执行以下命令：

```
php artisan api:swagger --setup
```

### 二、生成指定目录的Swagger API Josn

以 AftersalesBundle 举例如下：

```
php artisan api:swagger --output=src/AftersalesBundle/Http/Api/V1
```

执行完命令后，默认会在 `storage/app/apidocs` 目录下生成类似 `售后单商家端调用接口[1.0].json`文件。

可通过在 `.env` 中新增配置改变存储目录名称

```
SWAGGER_STORAGE_DIR=apidocs
```

### 三、启动服务查看和测试接口

可以通过 PHP 内置 server 快速启动

```
php -S 0.0.0.0:8005 -t public/
```

访问地址为：<http://127.0.0.1:8085/api-doc> 本机开发时，还需要将测试接口的地址修改为本地环境：

```
SWAGGER_API_HOST=127.0.0.1:8080
SWAGGER_API_BASE_PATH=/api
```

使用技巧： 在开发过程中可以，每次修改接口文档都需要重新生成接口文档，可以这样使用命令：

```
php artisan api:swagger --output=src/AftersalesBundle/Http/Api/V1 && php -S 0.0.0.0:8005 -t public/
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://espier.gitbook.io/espier/kuang-jia/intro/qing-qiu/controller.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
