# 网关调度机制介绍

## 概述
AppController.java 是 MicroCommunity 项目的统一网关入口控制器，主要负责接收所有HTTP请求并通过服务编码(service参数)将请求分发到相应的子服务。该控制器采用命令驱动架构设计，支持GET、POST、PUT、DELETE等多种HTTP方法。

## 核心入口方法

### 1. servicePost 方法
```java
@RequestMapping(path = "/{service:.+}", method = RequestMethod.POST)
public ResponseEntity<String> servicePost(@PathVariable String service,
                                         @RequestBody String postInfo,
                                         HttpServletRequest request)
```

### 2. serviceGet 方法  
```java
@RequestMapping(path = "/{service:.+}", method = RequestMethod.GET)
public ResponseEntity<String> serviceGet(@PathVariable String service,
                                        HttpServletRequest request)
```

## 请求处理流程

### 1. 头信息封装
- 调用 `getRequestInfo()` 方法初始化请求头信息
- 从HttpServletRequest中提取用户信息、token等
- 封装标准化的请求头信息到Map中

### 2. 服务编码解析
- `service` 参数作为服务编码放入头信息：`headers.put(CommonConstant.HTTP_SERVICE, service)`
- 请求方法标识：`headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_POST/GET)`
- 服务编码格式示例：`user.listUser`、`community.queryCommunities`

### 3. 权限校验
```java
// 通过IPrivilegeSMO进行权限校验
privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
```
- 校验用户是否有访问该接口的权限
- 基于菜单权限配置进行访问控制

### 4. 服务调用
```java
// POST请求调用
responseEntity = apiSMOImpl.doApi(postInfo, headers, request);

// GET请求调用  
responseEntity = apiSMOImpl.doApi(JSONObject.toJSONString(getParameterStringMap(request)), headers, request);
```

## 核心组件说明

### 1. IApiSMO 接口
```java
public interface IApiSMO {
    ResponseEntity<String> doApi(String body, Map<String, String> headers, HttpServletRequest request);
}
```
**作用**：服务调用入口，负责校验员工访问权限并转发请求

**实现类**：ApiSMOImpl
- 校验员工与商户的关系权限
- 重写用户ID和商户ID到请求头
- 调用IApiServiceSMO进行最终服务分发

### 2. IPrivilegeSMO 接口
```java
public interface IPrivilegeSMO {
    void hasPrivilege(RestTemplate restTemplate, IPageData pd, String resource);
}
```
**作用**：权限校验，验证用户是否有访问特定资源的权限

**实现类**：BootPrivilegeSMOImpl
- 继承DefaultAbstractComponentSMO
- 调用父类的hasPrivilege方法进行权限验证

### 3. IApiServiceSMO 接口
```java
public interface IApiServiceSMO {
    ResponseEntity<String> service(String reqJson, Map<String, String> headers);
}
```
**作用**：最终的服务分发核心，负责完整的请求处理流程

**实现类**：ApiServiceSMOImpl
- 解密请求报文（POST/PUT方法）
- 创建数据流对象
- 加载配置信息
- 权限校验
- 调用下游业务系统

## 服务编码解析机制

### 服务编码格式
- **标准格式**：`资源.操作`，如 `user.listUser`
- **路径格式**：`/{resource}/{action}`，如 `/user/listUser`

### 服务映射
通过 `CommonConstant.HTTP_SERVICE` 常量将服务编码传递到后端：
```java
headers.put(CommonConstant.HTTP_SERVICE, service);
```

## 异常处理机制

### 统一异常捕获
```java
try {
    // 业务处理逻辑
} catch (Throwable e) {
    logger.error("请求方法失败", e);
    responseEntity = ResultVo.error("请求发生异常，" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
```

### 异常类型
- **DecryptException**：解密异常
- **BusinessException**：业务异常
- **NoAuthorityException**：权限异常
- **InitConfigDataException**：配置初始化异常

## 架构图

```
客户端请求
    ↓
AppController (网关入口)
    ↓
servicePost/serviceGet 方法
    ↓
权限校验 (IPrivilegeSMO)
    ↓
服务调用 (IApiSMO → ApiSMOImpl)
    ↓
服务分发 (IApiServiceSMO → ApiServiceSMOImpl)
    ↓
数据流处理 (ApiDataFlow)
    ↓
配置加载 & 权限验证
    ↓
调用下游微服务 (dealCmd方法)
    ↓
返回响应结果
```

## 调用流程详解

### 1. 请求接收阶段
- 客户端发送请求到 `/app/{service}`
- AppController根据HTTP方法路由到对应方法
- 封装请求头信息和参数

### 2. 权限验证阶段  
- 通过AOP拦截器获取IPageData对象
- 调用IPrivilegeSMO验证用户权限
- 验证通过后继续处理

### 3. 服务分发阶段
- ApiSMOImpl进行员工权限校验
- 重写用户和商户信息到请求头
- 调用ApiServiceSMOImpl进行最终分发

### 4. 业务处理阶段
- ApiServiceSMOImpl创建数据流
- 加载应用路由配置
- 根据服务编码找到对应的AppService
- 通过dealCmd方法调用微服务

### 5. 响应返回阶段
- 处理微服务返回结果
- 统一封装响应格式
- 记录事务日志和耗时

## 关键配置说明

### 1. 请求头常量
```java
public final static String HTTP_SERVICE = "SERVICE";      // 服务编码
public final static String HTTP_METHOD = "METHOD";        // 请求方法
public final static String HTTP_ACTION = "ACTION";        // 操作动作
public final static String HTTP_RESOURCE = "RESOURCE";    // 资源类型
```

### 2. 权限相关常量
```java
public final static String CONTEXT_PAGE_DATA = "pd";      // 页面数据上下文
public final static String COOKIE_AUTH_TOKEN = "_java110_token_"; // 认证token
```

## 代码示例

### 典型POST请求处理
```java
// 1. 接收请求
@RequestMapping(path = "/{service:.+}", method = RequestMethod.POST)
public ResponseEntity<String> servicePost(@PathVariable String service,
                                         @RequestBody String postInfo,
                                         HttpServletRequest request) {
    
    // 2. 封装头信息
    Map<String, String> headers = new HashMap<>();
    this.getRequestInfo(request, headers);
    headers.put(CommonConstant.HTTP_SERVICE, service);
    headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_POST);
    
    // 3. 权限校验
    IPageData pd = (IPageData) request.getAttribute(CommonConstant.CONTEXT_PAGE_DATA);
    privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
    
    // 4. 服务调用
    ResponseEntity<String> responseEntity = apiSMOImpl.doApi(postInfo, headers, request);
    
    return responseEntity;
}
```

## 总结

AppController作为统一网关入口，通过标准化的服务编码机制实现了请求的智能分发。其核心特点包括：

1. **统一入口**：所有请求通过AppController统一处理
2. **权限控制**：多层次的权限验证机制
3. **服务发现**：基于服务编码的动态服务路由
4. **异常处理**：统一的异常捕获和错误处理
5. **日志记录**：完整的请求链路追踪和日志记录

这种设计使得系统具有良好的扩展性和维护性，新的服务只需按照规范注册服务编码即可自动接入网关调度体系。