# 工单系统 API

> API 接口文档 - 定义工单系统的完整 API 接口规范
>
> **版本**: v1.3  
> **模块标识**: `platform_tickets`  
> **基础路径**: `/api/v1/tickets`  
> **创建日期**: 2025-12-11  
> **更新日期**: 2025-12-11

---

## 📋 概述

### 认证要求

所有接口都需要 JWT 认证，通过 `Authorization: Bearer <token>` 请求头传递。

### 响应格式

遵循项目统一响应格式：

**成功响应**:
```json
{
  "success": true,
  "data": { ... },
  "message": "操作成功",
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

**错误响应**:
```json
{
  "success": false,
  "error": {
    "code": "TICKET_NOT_FOUND",
    "message": "工单不存在",
    "details": { ... }
  },
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

## 🎫 工单管理

### 创建工单

**POST** `/api/v1/tickets`

创建新的工单。

**权限**: `ticket:create`

**请求体**:
```json
{
  "title": "电脑无法开机",
  "description": "今天早上电脑突然无法开机，电源灯不亮，已尝试更换插座。",
  "categoryId": "uuid-category-id",
  "priority": "HIGH",
  "tags": ["hardware", "urgent"],
  "source": "WEB",
  "channelMetadata": {
    "conversationId": "uuid-ai-conversation-id",
    "sessionId": "uuid-session-id"
  },
  "language": "zh-CN",
  "attachments": [
    {
      "fileName": "error-photo.jpg",
      "fileUrl": "https://storage.example.com/uploads/error-photo.jpg",
      "fileSize": 102400,
      "mimeType": "image/jpeg"
    }
  ]
}
```

**请求体字段说明**:

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `title` | string | ✅ | 工单标题 (5-200 字符) |
| `description` | string | ✅ | 详细描述 (10-10000 字符) |
| `categoryId` | UUID | ✅ | 工单分类 ID |
| `priority` | enum | ❌ | 优先级: `LOW`, `MEDIUM`, `HIGH`, `URGENT` (默认 `MEDIUM`) |
| `tags` | string[] | ❌ | 标签列表 |
| `source` | enum | ❌ | 工单来源: `WEB`, `MOBILE`, `EMAIL`, `API`, `CHAT`, `PHONE`, `WALK_IN` (默认 `WEB`) |
| `channelMetadata` | object | ❌ | 来源渠道元数据（如 AI conversationId、邮件 messageId） |
| `language` | string | ❌ | 工单语言 (如 `zh-CN`, `en-US`) |
| `attachments` | array | ❌ | 附件列表 (最多 10 个) |

**成功响应** (201):
```json
{
  "success": true,
  "data": {
    "id": "uuid-ticket-id",
    "ticketNo": "TK-20251211-0001",
    "title": "电脑无法开机",
    "description": "今天早上电脑突然无法开机...",
    "categoryId": "uuid-category-id",
    "category": {
      "id": "uuid-category-id",
      "name": "IT 支持",
      "code": "IT_SUPPORT"
    },
    "priority": "HIGH",
    "status": "OPEN",
    "creatorId": "uuid-user-id",
    "creator": {
      "id": "uuid-user-id",
      "name": "张三",
      "email": "zhangsan@example.com"
    },
    "assigneeId": null,
    "assignee": null,
    "tags": ["hardware", "urgent"],
    "source": "WEB",
    "channelMetadata": null,
    "language": "zh-CN",
    "region": "CN",
    "tenantId": "uuid-tenant-id",
    "createdAt": "2025-12-11T10:00:00.000Z",
    "updatedAt": "2025-12-11T10:00:00.000Z",
    "attachments": [...]
  },
  "message": "工单创建成功",
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

**错误响应**:

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_CATEGORY_NOT_FOUND` | 404 | 分类不存在 |
| `TICKET_CATEGORY_INACTIVE` | 400 | 分类已停用 |
| `TICKET_ATTACHMENT_LIMIT_EXCEEDED` | 400 | 附件数量超过限制 |

---

### 获取工单列表

**GET** `/api/v1/tickets`

获取工单列表，支持多种筛选条件。

**权限**: 根据用户角色自动过滤

**查询参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `page` | number | ❌ | 页码 (默认 1) |
| `limit` | number | ❌ | 每页数量 (默认 20, 最大 100) |
| `status` | enum | ❌ | 状态筛选 |
| `statuses` | enum[] | ❌ | 多状态筛选 |
| `priority` | enum | ❌ | 优先级筛选 |
| `categoryId` | UUID | ❌ | 分类筛选 |
| `assigneeId` | UUID | ❌ | 处理人筛选 |
| `creatorId` | UUID | ❌ | 创建人筛选 |
| `keyword` | string | ❌ | 关键词搜索 (标题/编号) |
| `startDate` | date | ❌ | 创建时间起始 |
| `endDate` | date | ❌ | 创建时间结束 |
| `slaBreached` | boolean | ❌ | 是否超时 |
| `view` | string | ❌ | 预设视图: `my_created`, `my_assigned`, `my_group`, `all` |
| `sortBy` | string | ❌ | 排序字段: `createdAt`, `updatedAt`, `priority`, `dueAt` |
| `sortOrder` | string | ❌ | 排序方向: `asc`, `desc` |

**示例请求**:
```
GET /api/v1/tickets?status=IN_PROGRESS&priority=HIGH&sortBy=createdAt&sortOrder=desc
```

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "uuid-ticket-id",
        "ticketNo": "TK-20251211-0001",
        "title": "电脑无法开机",
        "priority": "HIGH",
        "status": "IN_PROGRESS",
        "category": {
          "id": "uuid-category-id",
          "name": "IT 支持",
          "code": "IT_SUPPORT"
        },
        "creator": {
          "id": "uuid-user-id",
          "name": "张三"
        },
        "assignee": {
          "id": "uuid-assignee-id",
          "name": "李四"
        },
        "createdAt": "2025-12-11T10:00:00.000Z",
        "updatedAt": "2025-12-11T11:00:00.000Z",
        "dueAt": "2025-12-12T10:00:00.000Z",
        "slaBreached": false
      }
    ],
    "total": 100,
    "page": 1,
    "limit": 20,
    "totalPages": 5,
    "hasNext": true,
    "hasPrev": false
  },
  "timestamp": "2025-12-11T10:00:00.000Z",
  "path": "/api/v1/tickets"
}
```

---

### 获取工单详情

**GET** `/api/v1/tickets/:id`

获取工单详细信息。

**权限**: 创建人/处理人/关注人/同组成员/管理员

**路径参数**:

| 参数 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | 工单 ID |

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "id": "uuid-ticket-id",
    "ticketNo": "TK-20251211-0001",
    "title": "电脑无法开机",
    "description": "今天早上电脑突然无法开机...",
    "category": {
      "id": "uuid-category-id",
      "name": "IT 支持",
      "code": "IT_SUPPORT"
    },
    "priority": "HIGH",
    "status": "IN_PROGRESS",
    "creator": {
      "id": "uuid-user-id",
      "name": "张三",
      "email": "zhangsan@example.com",
      "department": "研发部"
    },
    "assignee": {
      "id": "uuid-assignee-id",
      "name": "李四",
      "email": "lisi@example.com"
    },
    "assigneeGroup": {
      "id": "uuid-group-id",
      "name": "IT 支持组"
    },
    "watchers": [
      { "id": "uuid-watcher-id", "name": "王五" }
    ],
    "tags": ["hardware", "urgent"],
    "source": "WEB",
    "resolution": null,
    "rootCause": null,
    "sla": {
      "id": "uuid-sla-id",
      "name": "标准 SLA",
      "firstResponseDue": "2025-12-11T12:00:00.000Z",
      "resolutionDue": "2025-12-12T10:00:00.000Z",
      "firstResponseAt": "2025-12-11T10:30:00.000Z",
      "breached": false
    },
    "attachments": [
      {
        "id": "uuid-attachment-id",
        "fileName": "error-photo.jpg",
        "fileUrl": "https://...",
        "fileSize": 102400,
        "mimeType": "image/jpeg",
        "uploadedBy": "uuid-user-id",
        "createdAt": "2025-12-11T10:00:00.000Z"
      }
    ],
    "relatedTickets": [],
    "createdAt": "2025-12-11T10:00:00.000Z",
    "updatedAt": "2025-12-11T11:00:00.000Z",
    "firstResponseAt": "2025-12-11T10:30:00.000Z",
    "resolvedAt": null,
    "closedAt": null
  },
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

**错误响应**:

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_NOT_FOUND` | 404 | 工单不存在 |
| `TICKET_ACCESS_DENIED` | 403 | 无权访问该工单 |

---

### 更新工单

**PATCH** `/api/v1/tickets/:id`

更新工单信息。

**权限**: 创建人（部分字段）/处理人/管理员

**请求体**:
```json
{
  "title": "电脑无法开机 - 已确认是电源问题",
  "priority": "URGENT",
  "tags": ["hardware", "urgent", "power-issue"]
}
```

**可更新字段**:

| 字段 | 创建人 | 处理人 | 管理员 | 说明 |
|------|:------:|:------:|:------:|------|
| `title` | ✅ (OPEN 状态) | ✅ | ✅ | 标题 |
| `description` | ✅ (OPEN 状态) | ✅ | ✅ | 描述 |
| `priority` | ❌ | ✅ | ✅ | 优先级 |
| `categoryId` | ❌ | ✅ | ✅ | 分类 |
| `tags` | ✅ | ✅ | ✅ | 标签 |
| `resolution` | ❌ | ✅ | ✅ | 解决方案 |
| `rootCause` | ❌ | ✅ | ✅ | 根本原因 |

**成功响应** (200):
```json
{
  "success": true,
  "data": { ... },
  "message": "工单更新成功",
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

### 更新工单状态

**PATCH** `/api/v1/tickets/:id/status`

更新工单状态。

**权限**: 处理人/管理员

**请求体**:
```json
{
  "status": "IN_PROGRESS",
  "comment": "已开始处理，正在排查问题"
}
```

**状态流转规则**:

| 当前状态 | 允许变更为 |
|----------|-----------|
| `OPEN` | `ASSIGNED`, `IN_PROGRESS`, `CANCELLED` |
| `ASSIGNED` | `IN_PROGRESS`, `PENDING`, `CANCELLED` |
| `IN_PROGRESS` | `PENDING`, `RESOLVED`, `CANCELLED` |
| `PENDING` | `IN_PROGRESS`, `RESOLVED`, `CANCELLED` |
| `RESOLVED` | `CLOSED`, `IN_PROGRESS` (重新打开) |
| `CLOSED` | `OPEN` (重新打开，限 7 天内) |

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "id": "uuid-ticket-id",
    "status": "IN_PROGRESS",
    "previousStatus": "ASSIGNED",
    "updatedAt": "2025-12-11T11:00:00.000Z"
  },
  "message": "状态更新成功",
  "timestamp": "2025-12-11T11:00:00.000Z"
}
```

**错误响应**:

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_INVALID_STATUS_TRANSITION` | 400 | 无效的状态变更 |
| `TICKET_REOPEN_EXPIRED` | 400 | 重新打开超过时限 |

---

### 分配工单

**POST** `/api/v1/tickets/:id/assign`

将工单分配给处理人。

**权限**: `ticket:assign`

**请求体**:
```json
{
  "assigneeId": "uuid-assignee-id",
  "comment": "请尽快处理这个紧急问题"
}
```

**或分配给处理组**:
```json
{
  "assigneeGroupId": "uuid-group-id",
  "comment": "分配给 IT 支持组"
}
```

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "id": "uuid-ticket-id",
    "assigneeId": "uuid-assignee-id",
    "assignee": {
      "id": "uuid-assignee-id",
      "name": "李四"
    },
    "status": "ASSIGNED",
    "updatedAt": "2025-12-11T11:00:00.000Z"
  },
  "message": "工单分配成功",
  "timestamp": "2025-12-11T11:00:00.000Z"
}
```

---

### 转派工单

**POST** `/api/v1/tickets/:id/reassign`

将工单转派给其他处理人。

**权限**: 当前处理人/管理员

**请求体**:
```json
{
  "assigneeId": "uuid-new-assignee-id",
  "reason": "需要网络专家处理"
}
```

---

### 认领工单

**POST** `/api/v1/tickets/:id/claim`

从队列中认领工单。

**权限**: 处理组成员

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "id": "uuid-ticket-id",
    "assigneeId": "uuid-current-user-id",
    "status": "ASSIGNED"
  },
  "message": "工单认领成功",
  "timestamp": "2025-12-11T11:00:00.000Z"
}
```

---

### 解决工单

**POST** `/api/v1/tickets/:id/resolve`

标记工单为已解决。

**权限**: 处理人/管理员

**请求体**:
```json
{
  "resolution": "更换电源适配器后电脑恢复正常工作",
  "rootCause": "电源适配器老化导致供电不足"
}
```

---

### 关闭工单

**POST** `/api/v1/tickets/:id/close`

关闭已解决的工单。

**权限**: 创建人/处理人/管理员

**请求体**:
```json
{
  "comment": "问题已确认解决，关闭工单"
}
```

---

### 取消工单

**POST** `/api/v1/tickets/:id/cancel`

取消工单。

**权限**: 创建人 (OPEN 状态) / 管理员

**请求体**:
```json
{
  "reason": "问题已自行解决，不需要支持"
}
```

---

### 重新打开工单

**POST** `/api/v1/tickets/:id/reopen`

重新打开已关闭的工单。

**权限**: 创建人 (7 天内) / 管理员

**请求体**:
```json
{
  "reason": "问题复发，需要继续处理"
}
```

---

## 💬 工单评论

### 获取评论列表

**GET** `/api/v1/tickets/:id/comments`

获取工单的评论列表。

**查询参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `page` | number | ❌ | 页码 (默认 1) |
| `limit` | number | ❌ | 每页数量 (默认 20, 最大 100) |

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "uuid-comment-id",
        "content": "已开始排查问题",
        "type": "COMMENT",
        "isInternal": false,
        "visibilityScope": "ALL",
        "author": {
          "id": "uuid-author-id",
          "name": "李四"
        },
        "attachments": [],
        "mentionedUsers": [],
        "createdAt": "2025-12-11T10:30:00.000Z"
      },
      {
        "id": "uuid-comment-id-2",
        "content": "状态从 OPEN 变更为 IN_PROGRESS",
        "type": "STATUS_CHANGE",
        "isInternal": false,
        "visibilityScope": "ALL",
        "author": {
          "id": "uuid-author-id",
          "name": "李四"
        },
        "createdAt": "2025-12-11T10:30:00.000Z"
      }
    ],
    "total": 5,
    "page": 1,
    "limit": 20,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  },
  "timestamp": "2025-12-11T10:00:00.000Z",
  "path": "/api/v1/tickets/:id/comments"
}
```

**说明**: 
- 普通用户无法看到 `isInternal: true` 的内部评论
- `visibilityScope` 控制更细粒度的可见范围

---

### 添加评论

**POST** `/api/v1/tickets/:id/comments`

添加工单评论。

**权限**: 创建人/处理人/关注人

**请求体**:
```json
{
  "content": "请问电源灯是完全不亮还是闪烁？",
  "type": "COMMENT",
  "isInternal": false,
  "visibilityScope": "ALL",
  "mentionedUserIds": ["uuid-user-id"],
  "attachments": [
    {
      "fileName": "diagnostic-result.pdf",
      "fileUrl": "https://...",
      "fileSize": 51200,
      "mimeType": "application/pdf"
    }
  ]
}
```

**请求体字段说明**:

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `content` | string | ✅ | 评论内容 (1-5000 字符) |
| `type` | enum | ❌ | 评论类型: `COMMENT`, `AI_CONTEXT` (默认 `COMMENT`) |
| `isInternal` | boolean | ❌ | 是否内部评论 (默认 false) |
| `visibilityScope` | enum | ❌ | 可见范围: `ALL`, `AGENT_ONLY`, `GROUP_ONLY`, `INTERNAL` (默认 `ALL`) |
| `mentionedUserIds` | UUID[] | ❌ | @提醒的用户 |
| `attachments` | array | ❌ | 附件列表 |

**成功响应** (201):
```json
{
  "success": true,
  "data": {
    "id": "uuid-comment-id",
    "content": "请问电源灯是完全不亮还是闪烁？",
    "type": "COMMENT",
    "isInternal": false,
    "author": {
      "id": "uuid-author-id",
      "name": "李四"
    },
    "mentionedUsers": [
      { "id": "uuid-user-id", "name": "张三" }
    ],
    "attachments": [...],
    "createdAt": "2025-12-11T11:00:00.000Z"
  },
  "message": "评论添加成功",
  "timestamp": "2025-12-11T11:00:00.000Z"
}
```

---

### 删除评论

**DELETE** `/api/v1/tickets/:ticketId/comments/:commentId`

删除评论（软删除）。

**权限**: 评论作者 (5 分钟内) / 管理员

---

## 📎 工单附件

### 获取附件列表

**GET** `/api/v1/tickets/:id/attachments`

获取工单的所有附件。

**成功响应** (200):
```json
{
  "success": true,
  "data": [
    {
      "id": "uuid-attachment-id",
      "fileName": "error-photo.jpg",
      "fileUrl": "https://...",
      "fileSize": 102400,
      "mimeType": "image/jpeg",
      "uploadedBy": {
        "id": "uuid-user-id",
        "name": "张三"
      },
      "commentId": null,
      "createdAt": "2025-12-11T10:00:00.000Z"
    }
  ],
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

### 上传附件

**POST** `/api/v1/tickets/:id/attachments`

上传工单附件。

**权限**: 创建人/处理人

**请求**: `multipart/form-data`

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `file` | File | ✅ | 文件 (最大 20MB) |

**支持的文件类型**:
- 图片: jpg, jpeg, png, gif, webp
- 文档: pdf, doc, docx, xls, xlsx, ppt, pptx
- 文本: txt, csv
- 压缩: zip, rar

---

### 删除附件

**DELETE** `/api/v1/tickets/:ticketId/attachments/:attachmentId`

删除附件。

**权限**: 上传者/管理员

---

## 👁️ 工单关注

### 添加关注

**POST** `/api/v1/tickets/:id/watchers`

添加工单关注人。

**请求体**:
```json
{
  "userIds": ["uuid-user-id-1", "uuid-user-id-2"]
}
```

---

### 取消关注

**DELETE** `/api/v1/tickets/:id/watchers/:userId`

取消关注。

---

### 关注/取消关注自己

**POST** `/api/v1/tickets/:id/watch`

当前用户关注工单。

**DELETE** `/api/v1/tickets/:id/watch`

当前用户取消关注。

---

## 📊 工单活动日志

### 获取活动日志

**GET** `/api/v1/tickets/:id/activities`

获取工单的操作历史。

**查询参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `page` | number | ❌ | 页码 (默认 1) |
| `limit` | number | ❌ | 每页数量 (默认 50, 最大 100) |

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "uuid-activity-id",
        "type": "STATUS_CHANGED",
        "content": {
          "oldStatus": "OPEN",
          "newStatus": "IN_PROGRESS"
        },
        "operator": {
          "id": "uuid-operator-id",
          "name": "李四"
        },
        "createdAt": "2025-12-11T10:30:00.000Z"
      },
      {
        "id": "uuid-activity-id-2",
        "type": "ASSIGNED",
        "content": {
          "assigneeId": "uuid-assignee-id",
          "assigneeName": "李四"
        },
        "operator": {
          "id": "uuid-admin-id",
          "name": "管理员"
        },
        "createdAt": "2025-12-11T10:15:00.000Z"
      },
      {
        "id": "uuid-activity-id-3",
        "type": "CREATED",
        "content": {},
        "operator": {
          "id": "uuid-creator-id",
          "name": "张三"
        },
        "createdAt": "2025-12-11T10:00:00.000Z"
      }
    ],
    "total": 10,
    "page": 1,
    "limit": 50,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  },
  "timestamp": "2025-12-11T10:00:00.000Z",
  "path": "/api/v1/tickets/:id/activities"
}
```

---

## ⭐ 满意度评价

### 提交满意度评价

**POST** `/api/v1/tickets/:id/satisfaction`

对已解决的工单提交满意度评价。

**权限**: 工单创建人

**请求体**:
```json
{
  "rating": 5,
  "comment": "问题解决很快，服务态度很好！"
}
```

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `rating` | number | ✅ | 评分 (1-5) |
| `comment` | string | ❌ | 评价内容 |

**成功响应** (201):
```json
{
  "success": true,
  "data": {
    "id": "uuid-satisfaction-id",
    "ticketId": "uuid-ticket-id",
    "rating": 5,
    "comment": "问题解决很快，服务态度很好！",
    "createdAt": "2025-12-11T12:00:00.000Z"
  },
  "message": "评价提交成功",
  "timestamp": "2025-12-11T12:00:00.000Z"
}
```

---

## 📁 工单分类管理

### 获取分类列表

**GET** `/api/v1/tickets/categories`

获取工单分类列表。

**查询参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `includeInactive` | boolean | ❌ | 是否包含停用分类 (默认 false) |
| `flat` | boolean | ❌ | 是否扁平化返回 (默认 false) |

**成功响应** (200):
```json
{
  "success": true,
  "data": [
    {
      "id": "uuid-category-id",
      "name": "IT 支持",
      "code": "IT_SUPPORT",
      "icon": "computer",
      "description": "IT 相关问题支持",
      "defaultPriority": "MEDIUM",
      "isActive": true,
      "sortOrder": 1,
      "children": [
        {
          "id": "uuid-subcategory-id",
          "name": "硬件问题",
          "code": "IT_HARDWARE",
          "parentId": "uuid-category-id",
          "isActive": true
        },
        {
          "id": "uuid-subcategory-id-2",
          "name": "软件问题",
          "code": "IT_SOFTWARE",
          "parentId": "uuid-category-id",
          "isActive": true
        }
      ]
    },
    {
      "id": "uuid-category-id-2",
      "name": "行政服务",
      "code": "ADMIN_SERVICE",
      "icon": "building",
      "isActive": true,
      "children": []
    }
  ],
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

### 创建分类

**POST** `/api/v1/tickets/categories`

创建工单分类。

**权限**: `ticket:category:manage`

**请求体**:
```json
{
  "name": "IT 支持",
  "code": "IT_SUPPORT",
  "description": "IT 相关问题支持",
  "icon": "computer",
  "parentId": null,
  "defaultPriority": "MEDIUM",
  "defaultAssigneeGroupId": "uuid-group-id",
  "slaId": "uuid-sla-id",
  "sortOrder": 1
}
```

---

### 更新分类

**PATCH** `/api/v1/tickets/categories/:id`

更新工单分类。

**权限**: `ticket:category:manage`

---

### 停用/启用分类

**PATCH** `/api/v1/tickets/categories/:id/status`

**权限**: `ticket:category:manage`

**请求体**:
```json
{
  "isActive": false
}
```

---

## 👥 处理组管理

### 获取处理组列表

**GET** `/api/v1/tickets/groups`

获取处理组列表。

**权限**: `ticket:group:manage`

**成功响应** (200):
```json
{
  "success": true,
  "data": [
    {
      "id": "uuid-group-id",
      "name": "IT 支持组",
      "code": "IT_SUPPORT_GROUP",
      "description": "负责 IT 相关工单处理",
      "manager": {
        "id": "uuid-manager-id",
        "name": "组长张"
      },
      "members": [
        { "id": "uuid-member-1", "name": "成员1" },
        { "id": "uuid-member-2", "name": "成员2" }
      ],
      "memberCount": 5,
      "skills": ["hardware", "software", "network"],
      "assignmentStrategy": "LOAD_BALANCE",
      "isActive": true
    }
  ],
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

### 创建处理组

**POST** `/api/v1/tickets/groups`

**权限**: `ticket:group:manage`

**请求体**:
```json
{
  "name": "IT 支持组",
  "code": "IT_SUPPORT_GROUP",
  "description": "负责 IT 相关工单处理",
  "managerId": "uuid-manager-id",
  "memberIds": ["uuid-member-1", "uuid-member-2"],
  "skills": ["hardware", "software", "network"],
  "assignmentStrategy": "LOAD_BALANCE",
  "categoryIds": ["uuid-category-id"]
}
```

---

### 更新处理组

**PATCH** `/api/v1/tickets/groups/:id`

**权限**: `ticket:group:manage`

---

### 添加/移除组成员

**POST** `/api/v1/tickets/groups/:id/members`

**请求体**:
```json
{
  "userIds": ["uuid-user-id-1", "uuid-user-id-2"]
}
```

**DELETE** `/api/v1/tickets/groups/:id/members/:userId`

---

## ⏱️ SLA 管理

### 获取 SLA 列表

**GET** `/api/v1/tickets/slas`

**权限**: `ticket:sla:manage`

**成功响应** (200):
```json
{
  "success": true,
  "data": [
    {
      "id": "uuid-sla-id",
      "name": "标准 SLA",
      "description": "普通工单的服务等级",
      "firstResponseTime": {
        "low": 480,
        "medium": 240,
        "high": 60,
        "urgent": 15
      },
      "resolutionTime": {
        "low": 4320,
        "medium": 1440,
        "high": 480,
        "urgent": 120
      },
      "businessHours": {
        "start": "09:00",
        "end": "18:00",
        "timezone": "Asia/Shanghai",
        "weekdays": [1, 2, 3, 4, 5]
      },
      "excludeHolidays": true,
      "isActive": true,
      "isDefault": true
    }
  ],
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

### 创建 SLA

**POST** `/api/v1/tickets/slas`

**权限**: `ticket:sla:manage`

---

### 更新 SLA

**PATCH** `/api/v1/tickets/slas/:id`

**权限**: `ticket:sla:manage`

---

## 📈 统计分析

### 获取工单统计概览

**GET** `/api/v1/tickets/stats/overview`

**权限**: `ticket:admin` 或 处理组长

**查询参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `startDate` | date | ❌ | 统计起始日期 |
| `endDate` | date | ❌ | 统计结束日期 |
| `groupId` | UUID | ❌ | 按处理组筛选 |

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "total": {
      "count": 500,
      "open": 50,
      "inProgress": 100,
      "resolved": 300,
      "closed": 50
    },
    "byPriority": {
      "low": 100,
      "medium": 250,
      "high": 120,
      "urgent": 30
    },
    "byCategory": [
      { "categoryId": "uuid", "name": "IT 支持", "count": 300 },
      { "categoryId": "uuid", "name": "行政服务", "count": 200 }
    ],
    "sla": {
      "totalWithSla": 400,
      "breached": 20,
      "breachRate": 0.05,
      "avgFirstResponseMinutes": 45,
      "avgResolutionMinutes": 240
    },
    "satisfaction": {
      "totalRated": 280,
      "avgRating": 4.5,
      "distribution": {
        "1": 5,
        "2": 10,
        "3": 25,
        "4": 80,
        "5": 160
      }
    }
  },
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

### 获取趋势数据

**GET** `/api/v1/tickets/stats/trends`

**查询参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `startDate` | date | ✅ | 起始日期 |
| `endDate` | date | ✅ | 结束日期 |
| `granularity` | enum | ❌ | 粒度: `day`, `week`, `month` (默认 `day`) |

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "created": [
      { "date": "2025-12-01", "count": 15 },
      { "date": "2025-12-02", "count": 20 },
      { "date": "2025-12-03", "count": 18 }
    ],
    "resolved": [
      { "date": "2025-12-01", "count": 12 },
      { "date": "2025-12-02", "count": 18 },
      { "date": "2025-12-03", "count": 15 }
    ],
    "avgResolutionTime": [
      { "date": "2025-12-01", "minutes": 180 },
      { "date": "2025-12-02", "minutes": 200 },
      { "date": "2025-12-03", "minutes": 150 }
    ]
  },
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

### 获取人员绩效

**GET** `/api/v1/tickets/stats/performance`

**权限**: `ticket:admin` 或 处理组长

**查询参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `startDate` | date | ❌ | 起始日期 |
| `endDate` | date | ❌ | 结束日期 |
| `groupId` | UUID | ❌ | 按处理组筛选 |

**成功响应** (200):
```json
{
  "success": true,
  "data": [
    {
      "userId": "uuid-user-id",
      "name": "李四",
      "group": "IT 支持组",
      "metrics": {
        "assigned": 50,
        "resolved": 45,
        "avgResolutionMinutes": 180,
        "slaBreached": 2,
        "avgSatisfaction": 4.6,
        "currentLoad": 5
      }
    }
  ],
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

## ⚠️ 错误码

### 工单相关

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_NOT_FOUND` | 404 | 工单不存在 |
| `TICKET_ACCESS_DENIED` | 403 | 无权访问该工单 |
| `TICKET_INVALID_STATUS_TRANSITION` | 400 | 无效的状态变更 |
| `TICKET_ALREADY_ASSIGNED` | 400 | 工单已被分配 |
| `TICKET_NOT_ASSIGNED` | 400 | 工单未分配 |
| `TICKET_REOPEN_EXPIRED` | 400 | 重新打开超过时限 |
| `TICKET_ATTACHMENT_LIMIT_EXCEEDED` | 400 | 附件数量超限 |
| `TICKET_ATTACHMENT_SIZE_EXCEEDED` | 400 | 附件大小超限 |
| `TICKET_ATTACHMENT_TYPE_INVALID` | 400 | 附件类型不支持 |

### 分类相关

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_CATEGORY_NOT_FOUND` | 404 | 分类不存在 |
| `TICKET_CATEGORY_INACTIVE` | 400 | 分类已停用 |
| `TICKET_CATEGORY_CODE_EXISTS` | 400 | 分类编码已存在 |
| `TICKET_CATEGORY_HAS_CHILDREN` | 400 | 分类存在子分类，无法删除 |
| `TICKET_CATEGORY_HAS_TICKETS` | 400 | 分类下存在工单，无法删除 |

### 处理组相关

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_GROUP_NOT_FOUND` | 404 | 处理组不存在 |
| `TICKET_GROUP_CODE_EXISTS` | 400 | 处理组编码已存在 |
| `TICKET_GROUP_NO_AVAILABLE_MEMBER` | 400 | 处理组无可用成员 |

### 评论相关

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_COMMENT_NOT_FOUND` | 404 | 评论不存在 |
| `TICKET_COMMENT_DELETE_EXPIRED` | 400 | 评论删除超过时限 |

### SLA 相关

| 错误码 | HTTP 状态 | 说明 |
|--------|----------|------|
| `TICKET_SLA_NOT_FOUND` | 404 | SLA 配置不存在 |
| `TICKET_SLA_IN_USE` | 400 | SLA 正在使用中，无法删除 |

---

## 🤖 AI 智能助手集成

> 🔗 **关联模块**: `platform_ai_assistant` ([企业智能助手](../../../ai-assistant/docs/PRD.md))

### 从 AI 对话升级创建工单

**POST** `/api/v1/tickets/from-ai`

从 AI 智能助手对话升级创建工单，自动携带对话上下文。

**权限**: 登录用户

**请求体**:
```json
{
  "conversationId": "uuid-conversation-id",
  "sessionId": "uuid-session-id",
  "escalationReason": "AI 无法解决该问题",
  "title": "VPN 连接失败",
  "description": "按照 AI 提供的步骤操作后仍无法连接 VPN",
  "categoryId": "uuid-category-id",
  "priority": "HIGH",
  "includeConversationHistory": true
}
```

**请求体字段说明**:

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `conversationId` | UUID | ✅ | AI 对话 ID |
| `sessionId` | UUID | ✅ | AI 会话 ID |
| `escalationReason` | string | ❌ | 升级原因 |
| `title` | string | ✅ | 工单标题 |
| `description` | string | ✅ | 工单描述 |
| `categoryId` | UUID | ❌ | 工单分类（可由 AI 推荐） |
| `priority` | enum | ❌ | 优先级 |
| `includeConversationHistory` | boolean | ❌ | 是否携带对话历史（默认 true） |

**成功响应** (201):
```json
{
  "success": true,
  "data": {
    "id": "uuid-ticket-id",
    "ticketNo": "TK-20251211-0001",
    "title": "VPN 连接失败",
    "source": "CHAT",
    "channelMetadata": {
      "conversationId": "uuid-conversation-id",
      "sessionId": "uuid-session-id",
      "escalationReason": "AI 无法解决该问题"
    },
    "status": "OPEN",
    "aiContext": {
      "commentId": "uuid-comment-id",
      "messageCount": 5
    }
  },
  "message": "工单创建成功，已关联 AI 对话上下文",
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

**说明**:
- 自动设置 `source: CHAT`
- 对话历史作为 `AI_CONTEXT` 类型评论添加，`visibilityScope: AGENT_ONLY`
- 自动通知对应处理组

---

### 获取 AI 推荐分类

**POST** `/api/v1/tickets/ai/suggest-category`

根据用户描述，由 AI 推荐工单分类。

**权限**: 登录用户

**请求体**:
```json
{
  "description": "电脑无法连接公司 VPN，显示认证失败"
}
```

**成功响应** (200):
```json
{
  "success": true,
  "data": {
    "suggestedCategory": {
      "id": "uuid-category-id",
      "name": "IT 支持",
      "code": "IT_SUPPORT",
      "confidence": 0.92
    },
    "alternativeCategories": [
      {
        "id": "uuid-category-id-2",
        "name": "网络问题",
        "code": "NETWORK_ISSUE",
        "confidence": 0.75
      }
    ]
  },
  "timestamp": "2025-12-11T10:00:00.000Z"
}
```

---

## 📚 相关文档

- [PRD.md](./PRD.md) - 产品需求文档
- [ARCHITECTURE.md](./ARCHITECTURE.md) - 架构设计文档
- [TODO.md](./TODO.md) - 开发待办事项

---

**创建日期**: 2025-12-11  
**最后更新**: 2025-12-11  
**版本**: v1.3
