20 KiB
客服管理模块完整实现文档
项目信息
模块名称: 客服管理系统 (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 个路由:
{
"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 中的主菜单添加了客服管理模块:
{
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条/页)
核心交互流程:
-
批量选择:
- 用户勾选单个项目的复选框 →
handleSelectItem()更新selectedIds数组 - 用户点击全选复选框 →
handleSelectAll()一键选中/取消所有项目 - 选中项目时,表行背景高亮 (#f3f4f6)
- 用户勾选单个项目的复选框 →
-
批量操作 (仅在 selectedIds.length > 0 时显示):
- 批量删除:
handleBatchDelete()→ 弹窗确认 → 循环删除 → 刷新列表 - 批量启用:
handleBatchEnable()→ 更新状态为 1 → 刷新列表 - 批量禁用:
handleBatchDisable()→ 更新状态为 0 → 刷新列表
- 批量删除:
-
过滤搜索:
- 状态选择器: 支持 "启用/禁用/全部"
- 关键词输入: 模糊匹配 name 或 account 字段
- 查询按钮: 触发
handleSearch()重置页码到 1 并刷新 - 重置按钮: 清空所有过滤条件,恢复默认状态
样式亮点:
- 黄色警告条 (#fef3c7) 突出显示已选择的批量操作
- 选中行高亮 (#f3f4f6) 提供视觉反馈
- 按钮色差: 删除红色、启用绿色、禁用灰色
2. 客服话术 (service/script.uvue)
用途: 管理客服快速回复模板/话术库
主要功能:
- ✅ 话术列表展示 (ID、标题、内容、更新时间)
- ✅ 新增/编辑 - Modal 对话框表单
- ✅ 搜索过滤 - 按标题搜索,支持查询/重置
- ✅ 单项删除
- ✅ 分页支持 (10条/页)
- ✅ 表单验证 - 标题和内容必填,字符数限制
核心交互流程:
-
新增话术:
- 用户点击 "新增话术" 按钮 →
handleCreate()打开Modal - Modal 显示空表单 (标题、内容)
- 输入验证: 标题必填 (最多50字)、内容必填 (最多200字)
- 点击保存 →
handleSave()验证 → 调用saveScript()→ 关闭Modal → 刷新列表
- 用户点击 "新增话术" 按钮 →
-
编辑话术:
- 用户点击表行的 "编辑" 按钮 →
handleEdit(id)打开Modal - Modal 预填现有数据
- 修改内容后点击保存,流程同新增
- 用户点击表行的 "编辑" 按钮 →
-
搜索过滤:
- 用户在搜索框输入标题关键字 → 点击查询
handleSearch()重置页码到 1,调用getScriptList({ title: searchTitle })- 重置按钮清空搜索词,恢复所有数据
样式亮点:
- Modal 设计: overlay 半透明背景、卡片式内容框、smooth animation
- 表单标签: 红色
*标记必填字段 - 字数限制提示: 在表单下方显示 "XX/50" 或 "XX/200"
3. 用户留言 (service/message.uvue)
用途: 处理客户咨询、反馈和问题,管理回复状态
主要功能:
- ✅ 留言列表展示 (ID、用户、联系方式、内容、回复状态、时间)
- ✅ 批量选择 - 复选框批量选中
- ✅ 批量操作 - 批量标记已回复、批量删除
- ✅ 高级过滤 - 状态筛选 (已回复/未回复/全部)、关键词搜索
- ✅ 回复功能 - Modal 回复对话框,显示原留言内容
- ✅ 分页支持 (10条/页)
核心交互流程:
-
查看和过滤:
- 用户通过状态选择器筛选 (已回复/未回复)
- 通过关键词搜索 (匹配用户名或内容)
- 点击查询刷新列表,重置选中项
- 点击重置清空所有过滤条件
-
批量标记已回复:
- 用户选中多个未回复的留言 → 点击 "批量回复" 按钮
handleBatchReply()弹窗确认 → 状态更新为已回复 → 刷新列表
-
单项回复:
- 用户点击表行的 "回复" 按钮 →
handleReply(id)打开Modal - Modal 显示原留言内容 (灰色背景框展示)
- 用户在文本框输入回复内容 → 点击发送
handleSendReply()验证内容不为空 → 调用replyMessage()→ 关闭Modal → 刷新列表
- 用户点击表行的 "回复" 按钮 →
-
批量删除:
- 用户勾选项目 → 点击 "删除" 按钮 (批量操作栏)
handleBatchDelete()弹窗双重确认 → 循环删除 → 刷新列表
状态色差:
- 已回复 (status=1): 绿色背景 (#D4EDDA) 绿色文字
- 未回复 (status=0): 红色背景 (#F8D7DA) 红色文字
样式亮点:
- 回复内容框: 灰色背景 (#F5F5F5),显示原客户的留言内容,保持对话上下文
- Modal 表单: 标题和内容框分离,内容框为 textarea 便于输入较长回复
4. 自动回复 (service/autoReply.uvue)
用途: 设置关键词触发自动回复规则,提高回复效率
主要功能:
- ✅ 规则列表展示 (ID、关键词、回复内容、状态、更新时间)
- ✅ 批量选择 - 复选框批量选中
- ✅ 批量删除 - 选中多条规则一键删除
- ✅ 新增/编辑 - Modal 对话框,包含表单验证
- ✅ 搜索过滤 - 按关键词搜索,按状态筛选
- ✅ 单项删除和编辑
- ✅ 分页支持 (10条/页)
核心交互流程:
-
创建规则:
- 点击 "新增规则" →
handleCreate()打开Modal - 填写: 关键词 (必填) + 回复内容 (必填) + 启用/禁用状态
- 验证通过后保存 → 刷新列表
- 点击 "新增规则" →
-
编辑规则:
- 点击表行 "编辑" →
handleEdit(id)打开Modal - 修改规则后保存,流程同创建
- 点击表行 "编辑" →
-
搜索和过滤:
- 关键词搜索: 支持模糊匹配 keyword 字段
- 状态筛选: 启用/禁用/全部
- 查询按钮: 触发
handleSearch()应用过滤并重置页码
-
批量删除:
- 勾选多个规则 → 点击 "删除" (批量操作栏)
handleBatchDelete()弹窗确认 → 删除 → 刷新列表
样式特点:
- 状态徽章: 启用=绿色、禁用=红色,一目了然
- 批量操作栏: 黄色警告背景,突出批量操作的重要性
5. 客服配置 (service/config.uvue)
用途: 配置客服系统的全局参数
配置项:
- 🕒 工作时间 - 设置客服工作时间范围 (例: 09:00-18:00)
- 🤖 自动回复 - 启用/禁用自动回复功能
- 👋 欢迎语 - 设置客户进入客服的欢迎提示文案
交互流程:
- 页面加载时调用
loadConfig()获取现有配置 - 用户修改任意配置项 (输入框、文本域、选择器)
- 点击保存按钮 →
handleSave()调用saveServiceConfig()更新配置 - Toast 提示保存成功
样式设计:
- 表单布局: 每个配置项单独 form-group,清晰分离
- 标签样式: 深灰色标签,与输入框对齐
- 提交按钮: 主色调按钮,居中或右对齐
服务层实现 (service.uts)
类型定义
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 函数
客服列表
// 获取客服列表 - 支持关键词和状态过滤
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>
话术管理
// 获取话术列表 - 支持标题搜索
export const getScriptList = (params: any = {}): Promise<any>
// 参数: { page?, limit?, title? }
// 保存话术 (新增或编辑)
export const saveScript = (data: any): Promise<any>
// 删除话术
export const deleteScript = (id: number): Promise<any>
消息管理
// 获取留言列表 - 支持关键词和状态过滤
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>
自动回复
// 获取自动回复规则列表 - 支持关键词和状态过滤
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>
配置管理
// 获取客服配置
export const getServiceConfig = (): Promise<ServiceConfig>
// 保存客服配置
export const saveServiceConfig = (data: any): Promise<any>
Mock 数据实现
所有 API 函数使用 300ms 延迟 模拟网络请求,返回标准格式的 Mock 数据:
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. 统一的批量操作模式
设计原理: 所有列表页面都支持相同的批量操作流程
// 第一步: 提供复选框列
<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. 可靠的表单验证
实现方式:
// 在 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 结构:
<!-- 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:
@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)
性能优化
- 分页加载: 每页 10 条记录,支持前后翻页
- 搜索防抖: (可选) 在 handleSearch 中添加防抖逻辑
- 列表虚拟化: (可选) 大数据集时使用虚拟滚动
- 缓存策略: Mock 函数返回相同数据,实际 API 可添加缓存
扩展建议
短期优化
-
搜索防抖: 给输入框添加 debounce
const handleSearchInput = debounce(() => { page.value = 1; loadList(); }, 500); -
图表统计: 在客服列表顶部添加关键指标卡片
- 客服总数 / 在线数
- 今日消息数 / 回复率
- 平均回复时间
-
高级搜索: 支持日期范围、多条件组合等
中期功能
- 消息推送: 新消息实时提醒
- 客服分配: 自动分配客户给最空闲的客服
- 满意度评分: 客户评分和反馈展示
- 数据导出: CSV/Excel 导出列表数据
长期规划
- AI 辅助: 智能话术推荐
- 对话分析: NLP 情感分析、内容分类
- 知识库: 自学习话术库,自动完善
- 多渠道: 微信、QQ、邮件等多渠道集成
故障排查
问题: 列表不显示数据
原因: Service.uts 中的 getXxxList() 延迟返回
解决: 等待 300ms 或检查网络请求
问题: Modal 关闭后表单数据残留
原因: closeModal() 中没有重置 form
解决: 确保 closeModal 中调用 form.value = { ... }
问题: 批量操作后 selectAll 未重置
原因: loadList() 中没有重置 selectAll
解决: 在 loadList 末尾添加 selectAll.value = false
完整清单
已完成 ✅
- 5 个页面完整实现
- 服务层 Mock 数据
- 路由和菜单配置
- AdminLayout 集成
- 批量操作功能
- 搜索过滤功能
- Modal 对话框
- 表单验证
- 设计系统集成
- 文档完整
待实现 (可选)
- 真实 API 集成
- 搜索防抖
- 虚拟滚动
- 图表统计
- 消息推送
- 文件导出
文档最后更新: 2026-01-28
版本: 1.0.0 (Release)
维护者: AI Assistant