# 客服管理模块完整实现文档

## 项目信息

**模块名称**: 客服管理系统 (Service Management System)  
**实现日期**: 2026-01-28  
**完成度**: 100% ✅  
**对标**: CRMEB 客服管理模块一致性

---

## 模块架构

### 目录结构

```
pages/mall/admin/service/
├── index.uvue              # 客服列表 - 人员管理
├── script.uvue             # 客服话术 - 快速回复模板
├── message.uvue            # 用户留言 - 消息管理
├── autoReply.uvue          # 自动回复 - 关键词规则
├── config.uvue             # 客服配置 - 全局设置
└── service.uts             # 服务层 - 业务逻辑 & Mock API
```

### 路由配置

在 `pages/mall/pages.json` 中的 `pages/mall/admin` 子包添加了 5 个路由：

```json
{
  "path": "service/index",
  "style": { "navigationBarTitleText": "客服列表" }
},
{
  "path": "service/script",
  "style": { "navigationBarTitleText": "客服话术" }
},
{
  "path": "service/message",
  "style": { "navigationBarTitleText": "用户留言" }
},
{
  "path": "service/autoReply",
  "style": { "navigationBarTitleText": "自动回复" }
},
{
  "path": "service/config",
  "style": { "navigationBarTitleText": "客服配置" }
}
```

### 菜单配置

在 `layouts/admin/utils/menu.uts` 中的主菜单添加了客服管理模块：

```typescript
{
  id: 'service',
  title: '客服管理',
  icon: 'headset',
  path: '/pages/mall/admin/service/index',
  children: [
    { id: 'service-index', title: '客服列表', path: '/pages/mall/admin/service/index' },
    { id: 'service-script', title: '客服话术', path: '/pages/mall/admin/service/script' },
    { id: 'service-message', title: '用户留言', path: '/pages/mall/admin/service/message' },
    { id: 'service-autoReply', title: '自动回复', path: '/pages/mall/admin/service/autoReply' },
    { id: 'service-config', title: '客服配置', path: '/pages/mall/admin/service/config' }
  ]
}
```

---

## 页面功能详解

### 1. 客服列表 (service/index.uvue)

**用途**: 管理客服人员，分配工作状态，查看统计信息

**主要功能**:

- ✅ 客服人员列表展示 (ID、姓名、账号、头像、状态、创建时间)
- ✅ **批量选择** - 单项复选框和全选功能
- ✅ **批量操作** - 批量删除、批量启用、批量禁用
- ✅ **高级过滤** - 状态筛选、关键词搜索、查询/重置按钮
- ✅ 单项删除、编辑操作
- ✅ 分页支持 (10条/页)

**核心交互流程**:

1. **批量选择**:
   - 用户勾选单个项目的复选框 → `handleSelectItem()` 更新 `selectedIds` 数组
   - 用户点击全选复选框 → `handleSelectAll()` 一键选中/取消所有项目
   - 选中项目时，表行背景高亮 (#f3f4f6)

2. **批量操作** (仅在 selectedIds.length > 0 时显示):
   - 批量删除: `handleBatchDelete()` → 弹窗确认 → 循环删除 → 刷新列表
   - 批量启用: `handleBatchEnable()` → 更新状态为 1 → 刷新列表
   - 批量禁用: `handleBatchDisable()` → 更新状态为 0 → 刷新列表

3. **过滤搜索**:
   - 状态选择器: 支持 "启用/禁用/全部"
   - 关键词输入: 模糊匹配 name 或 account 字段
   - 查询按钮: 触发 `handleSearch()` 重置页码到 1 并刷新
   - 重置按钮: 清空所有过滤条件，恢复默认状态

**样式亮点**:

- 黄色警告条 (#fef3c7) 突出显示已选择的批量操作
- 选中行高亮 (#f3f4f6) 提供视觉反馈
- 按钮色差: 删除红色、启用绿色、禁用灰色

---

### 2. 客服话术 (service/script.uvue)

**用途**: 管理客服快速回复模板/话术库

**主要功能**:

- ✅ 话术列表展示 (ID、标题、内容、更新时间)
- ✅ **新增/编辑** - Modal 对话框表单
- ✅ **搜索过滤** - 按标题搜索，支持查询/重置
- ✅ 单项删除
- ✅ 分页支持 (10条/页)
- ✅ **表单验证** - 标题和内容必填，字符数限制

**核心交互流程**:

1. **新增话术**:
   - 用户点击 "新增话术" 按钮 → `handleCreate()` 打开Modal
   - Modal 显示空表单 (标题、内容)
   - 输入验证: 标题必填 (最多50字)、内容必填 (最多200字)
   - 点击保存 → `handleSave()` 验证 → 调用 `saveScript()` → 关闭Modal → 刷新列表

2. **编辑话术**:
   - 用户点击表行的 "编辑" 按钮 → `handleEdit(id)` 打开Modal
   - Modal 预填现有数据
   - 修改内容后点击保存，流程同新增

3. **搜索过滤**:
   - 用户在搜索框输入标题关键字 → 点击查询
   - `handleSearch()` 重置页码到 1，调用 `getScriptList({ title: searchTitle })`
   - 重置按钮清空搜索词，恢复所有数据

**样式亮点**:

- Modal 设计: overlay 半透明背景、卡片式内容框、smooth animation
- 表单标签: 红色 `*` 标记必填字段
- 字数限制提示: 在表单下方显示 "XX/50" 或 "XX/200"

---

### 3. 用户留言 (service/message.uvue)

**用途**: 处理客户咨询、反馈和问题，管理回复状态

**主要功能**:

- ✅ 留言列表展示 (ID、用户、联系方式、内容、回复状态、时间)
- ✅ **批量选择** - 复选框批量选中
- ✅ **批量操作** - 批量标记已回复、批量删除
- ✅ **高级过滤** - 状态筛选 (已回复/未回复/全部)、关键词搜索
- ✅ **回复功能** - Modal 回复对话框，显示原留言内容
- ✅ 分页支持 (10条/页)

**核心交互流程**:

1. **查看和过滤**:
   - 用户通过状态选择器筛选 (已回复/未回复)
   - 通过关键词搜索 (匹配用户名或内容)
   - 点击查询刷新列表，重置选中项
   - 点击重置清空所有过滤条件

2. **批量标记已回复**:
   - 用户选中多个未回复的留言 → 点击 "批量回复" 按钮
   - `handleBatchReply()` 弹窗确认 → 状态更新为已回复 → 刷新列表

3. **单项回复**:
   - 用户点击表行的 "回复" 按钮 → `handleReply(id)` 打开Modal
   - Modal 显示原留言内容 (灰色背景框展示)
   - 用户在文本框输入回复内容 → 点击发送
   - `handleSendReply()` 验证内容不为空 → 调用 `replyMessage()` → 关闭Modal → 刷新列表

4. **批量删除**:
   - 用户勾选项目 → 点击 "删除" 按钮 (批量操作栏)
   - `handleBatchDelete()` 弹窗双重确认 → 循环删除 → 刷新列表

**状态色差**:

- 已回复 (status=1): 绿色背景 (#D4EDDA) 绿色文字
- 未回复 (status=0): 红色背景 (#F8D7DA) 红色文字

**样式亮点**:

- 回复内容框: 灰色背景 (#F5F5F5)，显示原客户的留言内容，保持对话上下文
- Modal 表单: 标题和内容框分离，内容框为 textarea 便于输入较长回复

---

### 4. 自动回复 (service/autoReply.uvue)

**用途**: 设置关键词触发自动回复规则，提高回复效率

**主要功能**:

- ✅ 规则列表展示 (ID、关键词、回复内容、状态、更新时间)
- ✅ **批量选择** - 复选框批量选中
- ✅ **批量删除** - 选中多条规则一键删除
- ✅ **新增/编辑** - Modal 对话框，包含表单验证
- ✅ **搜索过滤** - 按关键词搜索，按状态筛选
- ✅ 单项删除和编辑
- ✅ 分页支持 (10条/页)

**核心交互流程**:

1. **创建规则**:
   - 点击 "新增规则" → `handleCreate()` 打开Modal
   - 填写: 关键词 (必填) + 回复内容 (必填) + 启用/禁用状态
   - 验证通过后保存 → 刷新列表

2. **编辑规则**:
   - 点击表行 "编辑" → `handleEdit(id)` 打开Modal
   - 修改规则后保存，流程同创建

3. **搜索和过滤**:
   - 关键词搜索: 支持模糊匹配 keyword 字段
   - 状态筛选: 启用/禁用/全部
   - 查询按钮: 触发 `handleSearch()` 应用过滤并重置页码

4. **批量删除**:
   - 勾选多个规则 → 点击 "删除" (批量操作栏)
   - `handleBatchDelete()` 弹窗确认 → 删除 → 刷新列表

**样式特点**:

- 状态徽章: 启用=绿色、禁用=红色，一目了然
- 批量操作栏: 黄色警告背景，突出批量操作的重要性

---

### 5. 客服配置 (service/config.uvue)

**用途**: 配置客服系统的全局参数

**配置项**:

- 🕒 **工作时间** - 设置客服工作时间范围 (例: 09:00-18:00)
- 🤖 **自动回复** - 启用/禁用自动回复功能
- 👋 **欢迎语** - 设置客户进入客服的欢迎提示文案

**交互流程**:

1. 页面加载时调用 `loadConfig()` 获取现有配置
2. 用户修改任意配置项 (输入框、文本域、选择器)
3. 点击保存按钮 → `handleSave()` 调用 `saveServiceConfig()` 更新配置
4. Toast 提示保存成功

**样式设计**:

- 表单布局: 每个配置项单独 form-group，清晰分离
- 标签样式: 深灰色标签，与输入框对齐
- 提交按钮: 主色调按钮，居中或右对齐

---

## 服务层实现 (service.uts)

### 类型定义

```typescript
export type ServiceItem = {
  id: number;
  name: string; // 客服名称
  account: string; // 账号
  avatar: string; // 头像URL
  status: number; // 状态 (1=启用, 0=禁用)
  created_at: string; // 创建时间
};

export type ScriptItem = {
  id: number;
  title: string; // 话术标题
  content: string; // 话术内容
  updated_at: string; // 更新时间
};

export type MessageItem = {
  id: number;
  user: string; // 客户名称
  contact: string; // 联系方式
  content: string; // 留言内容
  status: number; // 回复状态 (1=已回复, 0=未回复)
  created_at: string; // 创建时间
};

export type AutoReplyItem = {
  id: number;
  keyword: string; // 触发关键词
  reply: string; // 回复内容
  status: number; // 启用状态
  updated_at: string; // 更新时间
};

export type ServiceConfig = {
  workTime: string; // 工作时间
  autoReply: number; // 自动回复启用状态
  welcomeText: string; // 欢迎语
};
```

### 核心 API 函数

#### 客服列表

```typescript
// 获取客服列表 - 支持关键词和状态过滤
export const getServiceList = (params: any = {}): Promise<any>
// 参数: { page?, limit?, keyword?, status? }
// 返回: { items: ServiceItem[], total: number }

// 删除单个客服
export const deleteService = (id: number): Promise<any>

// 批量删除客服
export const batchDeleteService = (ids: number[]): Promise<any>

// 批量更新客服状态
export const batchUpdateServiceStatus = (ids: number[], status: number): Promise<any>
```

#### 话术管理

```typescript
// 获取话术列表 - 支持标题搜索
export const getScriptList = (params: any = {}): Promise<any>
// 参数: { page?, limit?, title? }

// 保存话术 (新增或编辑)
export const saveScript = (data: any): Promise<any>

// 删除话术
export const deleteScript = (id: number): Promise<any>
```

#### 消息管理

```typescript
// 获取留言列表 - 支持关键词和状态过滤
export const getMessageList = (params: any = {}): Promise<any>
// 参数: { page?, limit?, keyword?, status? }

// 回复消息
export const replyMessage = (id: number, data: any): Promise<any>

// 删除消息
export const deleteMessage = (id: number): Promise<any>

// 批量标记为已回复
export const batchReplyMessage = (ids: number[]): Promise<any>

// 批量删除消息
export const batchDeleteMessage = (ids: number[]): Promise<any>
```

#### 自动回复

```typescript
// 获取自动回复规则列表 - 支持关键词和状态过滤
export const getAutoReplyList = (params: any = {}): Promise<any>
// 参数: { page?, limit?, keyword?, status? }

// 保存规则 (新增或编辑)
export const saveAutoReply = (data: any): Promise<any>

// 删除规则
export const deleteAutoReply = (id: number): Promise<any>

// 批量删除规则
export const batchDeleteAutoReply = (ids: number[]): Promise<any>
```

#### 配置管理

```typescript
// 获取客服配置
export const getServiceConfig = (): Promise<ServiceConfig>

// 保存客服配置
export const saveServiceConfig = (data: any): Promise<any>
```

### Mock 数据实现

所有 API 函数使用 **300ms 延迟** 模拟网络请求，返回标准格式的 Mock 数据：

```typescript
export const getServiceList = (params: any = {}): Promise<any> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      // 1. 先定义完整数据集
      let items = [
        { id: 1, name: '张客服', ... },
        { id: 2, name: '李客服', ... },
        ...
      ]

      // 2. 根据参数过滤
      if (params.keyword) {
        items = items.filter(item =>
          item.name.includes(params.keyword) || item.account.includes(params.keyword)
        )
      }
      if (params.status !== undefined) {
        items = items.filter(item => item.status === params.status)
      }

      // 3. 分页处理
      const total = items.length
      const start = ((params.page || 1) - 1) * (params.limit || 10)
      const end = start + (params.limit || 10)

      // 4. 返回分页结果
      resolve({
        items: items.slice(start, end),
        total
      })
    }, 300)
  })
}
```

---

## 核心特性

### 1. 统一的批量操作模式

**设计原理**: 所有列表页面都支持相同的批量操作流程

```javascript
// 第一步: 提供复选框列
<view class="cell cell-checkbox">
  <input type="checkbox" v-model="selectAll" @change="handleSelectAll">
</view>

// 第二步: 跟踪选中状态
const selectedIds = ref<number[]>([])
const selectAll = ref<boolean>(false)

// 第三步: 显示操作栏 (conditional)
<view v-if="selectedIds.length > 0" class="batch-actions">
  <!-- 批量操作按钮 -->
</view>

// 第四步: 实现操作逻辑
const handleBatchDelete = () => {
  // 显示确认对话框
  // 循环删除 selectedIds 中的每一项
  // 刷新列表
  // 清空选中状态
}
```

**优势**:

- 用户体验一致，学习成本低
- 代码易维护，模式统一
- 支持全选/反选，操作高效

### 2. 可靠的表单验证

**实现方式**:

```javascript
// 在 handleSave() 中执行验证
const handleSave = async () => {
  // 验证必填字段
  if (!form.value.keyword.trim()) {
    uni.showToast({ title: "请输入关键词", icon: "none" });
    return;
  }
  if (!form.value.reply.trim()) {
    uni.showToast({ title: "请输入回复内容", icon: "none" });
    return;
  }

  // 验证字符长度
  if (form.value.keyword.length > 50) {
    uni.showToast({ title: "关键词不能超过50个字符", icon: "none" });
    return;
  }

  // 验证通过，保存
  await saveAutoReply(form.value);
  uni.showToast({ title: "保存成功", icon: "success" });
  closeModal();
  loadList();
};
```

**错误提示**: 使用 Toast 展示，即时反馈

### 3. 强大的搜索和过滤

**支持的过滤类型**:

| 页面     | 搜索字段              | 过滤字段      | 重置功能    |
| -------- | --------------------- | ------------- | ----------- |
| 客服列表 | 名称/账号 (keyword)   | 状态 (status) | ✅ 清空所有 |
| 话术库   | 标题 (title)          | 无            | ✅ 清空搜索 |
| 留言     | 用户名/内容 (keyword) | 状态 (status) | ✅ 清空所有 |
| 自动回复 | 关键词/内容 (keyword) | 状态 (status) | ✅ 清空所有 |

**实现细节**:

- 搜索和过滤时，自动重置页码到第 1 页
- 点击重置按钮，同时清空搜索词和过滤条件
- 支持多条件组合过滤 (AND 逻辑)

### 4. Modal 对话框框架

**统一的 Modal 结构**:

```vue
<!-- Modal 容器 -->
<view v-if="showModal" class="modal-overlay" @click.self="closeModal">
  <!-- 内容卡片 -->
  <view class="modal-content" @click.stop>
    <!-- 头部: 标题 + 关闭按钮 -->
    <view class="modal-header">
      <text class="modal-title">标题</text>
      <button class="modal-close" @click="closeModal">×</button>
    </view>

    <!-- 主体: 表单或内容 -->
    <view class="modal-body">
      <!-- 内容区域 -->
    </view>

    <!-- 尾部: 操作按钮 -->
    <view class="modal-footer">
      <button class="btn-cancel" @click="closeModal">取消</button>
      <button class="btn-confirm" @click="handleAction">确认</button>
    </view>
  </view>
</view>
```

**样式特点**:

- 半透明黑色背景 (rgba(0,0,0,0.5))
- 白色卡片，圆角边界，阴影深度
- Z-index 1000，置于顶层
- 点击背景可关闭 (@click.self)

### 5. 设计系统整合

所有样式都遵循统一的设计 token:

```scss
@import '@/uni.scss';

// 颜色系统
$primary-color: #007AFF        // 主题色 (蓝色)
$success-color: #4CAF50        // 成功 (绿色)
$error-color: #F56C6C          // 错误 (红色)
$text-primary: #1F2937         // 主文字
$text-secondary: #6B7280       // 次级文字
$border-color: #E5E7EB         // 边框
$background-primary: #FFFFFF   // 主背景
$background-secondary: #F9FAFB // 次级背景

// 间距
$space-xs: 4px
$space-sm: 8px
$space-md: 12px
$space-lg: 16px
$space-xl: 24px

// 圆角
$radius-sm: 4px
$radius-lg: 8px

// 字体
$font-size-xs: 12px
$font-size-sm: 13px
$font-size-base: 14px
$font-size-lg: 16px
```

---

## 对标 CRMEB 的实现细节

### UI 设计对齐

| 特性      | CRMEB           | 本实现                    | 说明               |
| --------- | --------------- | ------------------------- | ------------------ |
| 列表布局  | 表格 + 操作栏   | ✅ 表格 + 操作栏          | 一致               |
| 批量操作  | 复选框 + 工具栏 | ✅ 复选框 + 黄色工具栏    | 一致，增强了可视性 |
| 新增/编辑 | Modal 对话框    | ✅ 自定义Modal            | 功能等价           |
| 搜索过滤  | 行内过滤器      | ✅ 过滤行 + 查询/重置按钮 | 功能完整           |
| 分页      | 底部分页        | ✅ 底部分页               | 一致               |
| 状态提示  | 状态徽章        | ✅ 徽章样式               | 一致               |

### 功能完整性

```
✅ 客服列表:      人员管理、状态控制、批量操作
✅ 客服话术:      模板管理、快速搜索、Modal 编辑
✅ 用户留言:      消息管理、回复功能、状态跟踪
✅ 自动回复:      规则管理、关键词匹配、启用/禁用
✅ 客服配置:      全局设置、工作时间、欢迎语

超出 CRMEB:        Modal 验证、高级过滤、批量状态更新
```

---

## 技术栈

- **框架**: uni-app X + Vue 3 Composition API
- **语言**: UTS (TypeScript for uni-app)
- **组件**: AdminLayout (自定义布局)
- **状态**: ref() + computed() (响应式)
- **样式**: SCSS + 设计系统变量
- **数据**: Mock 服务层 (可切换真实 API)

---

## 性能优化

1. **分页加载**: 每页 10 条记录，支持前后翻页
2. **搜索防抖**: (可选) 在 handleSearch 中添加防抖逻辑
3. **列表虚拟化**: (可选) 大数据集时使用虚拟滚动
4. **缓存策略**: Mock 函数返回相同数据，实际 API 可添加缓存

---

## 扩展建议

### 短期优化

1. **搜索防抖**: 给输入框添加 debounce

   ```typescript
   const handleSearchInput = debounce(() => {
     page.value = 1;
     loadList();
   }, 500);
   ```

2. **图表统计**: 在客服列表顶部添加关键指标卡片
   - 客服总数 / 在线数
   - 今日消息数 / 回复率
   - 平均回复时间

3. **高级搜索**: 支持日期范围、多条件组合等

### 中期功能

1. **消息推送**: 新消息实时提醒
2. **客服分配**: 自动分配客户给最空闲的客服
3. **满意度评分**: 客户评分和反馈展示
4. **数据导出**: CSV/Excel 导出列表数据

### 长期规划

1. **AI 辅助**: 智能话术推荐
2. **对话分析**: NLP 情感分析、内容分类
3. **知识库**: 自学习话术库，自动完善
4. **多渠道**: 微信、QQ、邮件等多渠道集成

---

## 故障排查

### 问题: 列表不显示数据

**原因**: Service.uts 中的 getXxxList() 延迟返回  
**解决**: 等待 300ms 或检查网络请求

### 问题: Modal 关闭后表单数据残留

**原因**: closeModal() 中没有重置 form  
**解决**: 确保 closeModal 中调用 `form.value = { ... }`

### 问题: 批量操作后 selectAll 未重置

**原因**: loadList() 中没有重置 selectAll  
**解决**: 在 loadList 末尾添加 `selectAll.value = false`

---

## 完整清单

### 已完成 ✅

- [x] 5 个页面完整实现
- [x] 服务层 Mock 数据
- [x] 路由和菜单配置
- [x] AdminLayout 集成
- [x] 批量操作功能
- [x] 搜索过滤功能
- [x] Modal 对话框
- [x] 表单验证
- [x] 设计系统集成
- [x] 文档完整

### 待实现 (可选)

- [ ] 真实 API 集成
- [ ] 搜索防抖
- [ ] 虚拟滚动
- [ ] 图表统计
- [ ] 消息推送
- [ ] 文件导出

---

**文档最后更新**: 2026-01-28  
**版本**: 1.0.0 (Release)  
**维护者**: AI Assistant
