You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
12 KiB
378 lines
12 KiB
// pages/customer-service/index.js
|
|
Page({
|
|
// 客服数据,将从后端动态获取
|
|
data: {
|
|
customerServices: [],
|
|
filteredServices: [],
|
|
searchKeyword: '',
|
|
selectedArea: '全部',
|
|
totalCount: 0,
|
|
onlineCount: 0
|
|
},
|
|
|
|
// 获取客服列表的方法
|
|
async fetchCustomerServices() {
|
|
try {
|
|
console.log('开始请求客服列表...');
|
|
// 导入API工具并使用正确的请求方法
|
|
const api = require('../../utils/api');
|
|
|
|
const res = await new Promise((resolve, reject) => {
|
|
wx.request({
|
|
url: 'http://localhost:3003/api/managers',
|
|
method: 'GET',
|
|
timeout: 15000,
|
|
header: {
|
|
'content-type': 'application/json'
|
|
},
|
|
success: resolve,
|
|
fail: (error) => {
|
|
console.error('网络请求失败:', error);
|
|
reject(error);
|
|
}
|
|
});
|
|
});
|
|
|
|
console.log('API响应状态码:', res?.statusCode);
|
|
console.log('API响应数据:', res?.data ? JSON.stringify(res.data) : 'undefined');
|
|
|
|
// 更宽松的响应检查,确保能处理各种有效的响应格式
|
|
if (res && res.statusCode === 200 && res.data) {
|
|
// 无论success字段是否存在,只要有data字段就尝试处理
|
|
const dataSource = res.data.data || res.data;
|
|
if (Array.isArray(dataSource)) {
|
|
const processedData = dataSource.map(item => ({
|
|
id: item.id || `id_${Date.now()}_${Math.random()}`, // 确保有id
|
|
managerId: item.managerId || '',
|
|
managercompany: item.managercompany || '',
|
|
managerdepartment: item.managerdepartment || '',
|
|
organization: item.organization || '',
|
|
projectName: item.projectName || '',
|
|
name: item.name || '未知',
|
|
alias: item.alias || item.name || '未知',
|
|
phoneNumber: item.phoneNumber || '',
|
|
avatarUrl: item.avatar || item.avatarUrl || '', // 兼容avatar和avatarUrl
|
|
score: Math.floor(Math.random() * 20) + 980, // 随机生成分数
|
|
isOnline: !!item.online, // 转换为布尔值
|
|
responsibleArea: `${this.getRandomArea()}鸡蛋采购`,
|
|
experience: this.getRandomExperience(),
|
|
serviceCount: this.getRandomNumber(100, 300),
|
|
purchaseCount: this.getRandomNumber(10000, 30000),
|
|
profitIncreaseRate: this.getRandomNumber(10, 25),
|
|
profitFarmCount: this.getRandomNumber(50, 200),
|
|
skills: this.getRandomSkills()
|
|
}));
|
|
console.log('处理后的数据数量:', processedData.length);
|
|
return processedData;
|
|
} else {
|
|
console.error('响应数据格式错误,不是预期的数组格式:', dataSource);
|
|
return [];
|
|
}
|
|
} else {
|
|
console.error('获取客服列表失败,状态码:', res?.statusCode, '响应数据:', res?.data);
|
|
return [];
|
|
}
|
|
} catch (error) {
|
|
console.error('请求客服列表出错:', error);
|
|
// 网络错误时显示提示
|
|
wx.showToast({
|
|
title: '网络请求失败,请检查网络连接',
|
|
icon: 'none'
|
|
});
|
|
return [];
|
|
}
|
|
},
|
|
|
|
// 辅助函数:生成随机区域
|
|
getRandomArea() {
|
|
const areas = ['华北区', '华东区', '华南区', '全国', '西南区', '西北区', '东北区'];
|
|
return areas[Math.floor(Math.random() * areas.length)];
|
|
},
|
|
|
|
// 辅助函数:生成随机工作经验
|
|
getRandomExperience() {
|
|
const experiences = ['1-2年', '1-3年', '2-3年', '3-5年', '5年以上'];
|
|
return experiences[Math.floor(Math.random() * experiences.length)];
|
|
},
|
|
|
|
// 辅助函数:生成随机数字
|
|
getRandomNumber(min, max) {
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
},
|
|
|
|
// 辅助函数:生成随机技能
|
|
getRandomSkills() {
|
|
const allSkills = ['渠道拓展', '供应商维护', '质量把控', '精准把控市场价格', '谈判技巧', '库存管理'];
|
|
const skillCount = Math.floor(Math.random() * 3) + 2; // 2-4个技能
|
|
const selectedSkills = [];
|
|
|
|
while (selectedSkills.length < skillCount) {
|
|
const skill = allSkills[Math.floor(Math.random() * allSkills.length)];
|
|
if (!selectedSkills.includes(skill)) {
|
|
selectedSkills.push(skill);
|
|
}
|
|
}
|
|
|
|
return selectedSkills;
|
|
},
|
|
|
|
// 设置WebSocket监听客服状态变化
|
|
setupWebSocketListener() {
|
|
const ws = getApp().globalData.webSocketManager;
|
|
const app = getApp();
|
|
const userInfo = app.globalData.userInfo || {};
|
|
const isManager = userInfo.userType === 'manager' || userInfo.type === 'manager';
|
|
|
|
if (ws) {
|
|
// 监听客服状态更新消息
|
|
ws.on('customerServiceStatusUpdate', (data) => {
|
|
console.log('收到客服状态更新:', data);
|
|
// 更新对应客服的在线状态
|
|
const customerServiceList = this.data.customerServices;
|
|
const updatedList = customerServiceList.map(item => {
|
|
if (item.id === data.id || item.managerId === data.managerId) {
|
|
return { ...item, isOnline: data.isOnline };
|
|
}
|
|
return item;
|
|
});
|
|
|
|
const onlineCount = updatedList.filter(item => item.isOnline).length;
|
|
|
|
this.setData({
|
|
customerServices: updatedList,
|
|
onlineCount: onlineCount
|
|
});
|
|
|
|
// 重新应用筛选
|
|
this.filterServices();
|
|
});
|
|
|
|
// 如果当前用户是客服,立即进行认证
|
|
if (isManager && userInfo.userId) {
|
|
console.log('客服用户登录,进行WebSocket认证:', userInfo.userId);
|
|
// 使用userId作为managerId进行认证,确保与服务器端onlineManagers中的键匹配
|
|
ws.authenticate();
|
|
}
|
|
}
|
|
},
|
|
|
|
// 定期刷新客服列表(每30秒)
|
|
startPeriodicRefresh() {
|
|
this.refreshTimer = setInterval(() => {
|
|
console.log('定期刷新客服列表...');
|
|
this.loadCustomerServices();
|
|
}, 30000);
|
|
},
|
|
|
|
// 停止定期刷新
|
|
stopPeriodicRefresh() {
|
|
if (this.refreshTimer) {
|
|
clearInterval(this.refreshTimer);
|
|
this.refreshTimer = null;
|
|
}
|
|
},
|
|
|
|
// 加载客服列表
|
|
async loadCustomerServices() {
|
|
console.log('开始加载客服列表...');
|
|
// 确保在开始时调用hideLoading,防止重复调用showLoading
|
|
try {
|
|
wx.hideLoading();
|
|
} catch (e) {
|
|
console.log('没有正在显示的loading');
|
|
}
|
|
|
|
wx.showLoading({ title: '加载中...' });
|
|
try {
|
|
const services = await this.fetchCustomerServices();
|
|
console.log('获取到的客服数量:', services.length);
|
|
|
|
// 计算在线数量
|
|
const onlineCount = services.filter(item => item.isOnline).length;
|
|
console.log('在线客服数量:', onlineCount);
|
|
|
|
// 更新数据
|
|
this.setData({
|
|
customerServices: services,
|
|
totalCount: services.length,
|
|
onlineCount: onlineCount
|
|
});
|
|
console.log('数据更新成功');
|
|
|
|
// 应用当前的筛选条件
|
|
this.filterServices();
|
|
console.log('筛选条件应用完成');
|
|
|
|
// 如果没有数据,显示提示(确保在hideLoading后显示)
|
|
if (services.length === 0) {
|
|
setTimeout(() => {
|
|
wx.showToast({
|
|
title: '暂无客服数据',
|
|
icon: 'none',
|
|
duration: 2000
|
|
});
|
|
}, 100);
|
|
}
|
|
} catch (error) {
|
|
console.error('加载客服列表失败:', error);
|
|
// 确保在hideLoading后显示错误提示
|
|
setTimeout(() => {
|
|
wx.showToast({
|
|
title: '加载失败,请重试',
|
|
icon: 'none',
|
|
duration: 2000
|
|
});
|
|
}, 100);
|
|
} finally {
|
|
wx.hideLoading();
|
|
}
|
|
},
|
|
|
|
onLoad: function () {
|
|
// 初始化WebSocket连接
|
|
const app = getApp();
|
|
if (!app.globalData.webSocketManager) {
|
|
// 如果WebSocket管理器还没初始化,从utils导入
|
|
const WebSocketManager = require('../../utils/websocket').default;
|
|
app.globalData.webSocketManager = WebSocketManager;
|
|
|
|
// 尝试连接WebSocket
|
|
WebSocketManager.connect('ws://localhost:3003');
|
|
}
|
|
|
|
// 设置WebSocket监听
|
|
this.setupWebSocketListener();
|
|
|
|
// 加载客服列表
|
|
this.loadCustomerServices();
|
|
|
|
// 启动定期刷新
|
|
this.startPeriodicRefresh();
|
|
|
|
// 检查当前用户身份
|
|
this.checkUserType();
|
|
},
|
|
|
|
/**
|
|
* 检查当前用户身份
|
|
*/
|
|
checkUserType: function() {
|
|
const app = getApp();
|
|
const userInfo = app.globalData.userInfo || {};
|
|
const isManager = userInfo.userType === 'manager' || userInfo.type === 'manager';
|
|
console.log('当前用户身份检查:', { isManager, userType: userInfo.userType });
|
|
this.setData({
|
|
isCurrentUserManager: isManager
|
|
});
|
|
},
|
|
|
|
onShow() {
|
|
// 更新自定义tabBar状态
|
|
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
|
this.getTabBar().setData({
|
|
selected: -1 // 不选中任何tab
|
|
});
|
|
}
|
|
|
|
// 当页面显示时重新加载数据,确保数据最新
|
|
this.loadCustomerServices();
|
|
},
|
|
|
|
onUnload: function() {
|
|
// 停止定期刷新
|
|
this.stopPeriodicRefresh();
|
|
|
|
// 清理WebSocket事件监听
|
|
const ws = getApp().globalData.webSocketManager;
|
|
if (ws) {
|
|
ws.off('customerServiceStatusUpdate');
|
|
}
|
|
},
|
|
|
|
onSearch: function (e) {
|
|
const keyword = e.detail.value;
|
|
this.setData({
|
|
searchKeyword: keyword
|
|
});
|
|
this.filterServices();
|
|
},
|
|
|
|
onAreaFilter: function () {
|
|
// 区域筛选弹窗 - 鸡蛋采购区域
|
|
wx.showActionSheet({
|
|
itemList: ['全部', '华北区', '华东区', '华南区', '全国', '西南区', '西北区', '东北区'],
|
|
success: res => {
|
|
const areas = ['全部', '华北区', '华东区', '华南区', '全国', '西南区', '西北区', '东北区'];
|
|
const selectedArea = areas[res.tapIndex];
|
|
this.setData({
|
|
selectedArea: selectedArea
|
|
});
|
|
this.filterServices();
|
|
}
|
|
});
|
|
},
|
|
|
|
filterServices: function () {
|
|
const { customerServices, searchKeyword, selectedArea } = this.data;
|
|
|
|
let filtered = customerServices;
|
|
|
|
// 关键词搜索
|
|
if (searchKeyword) {
|
|
const keyword = searchKeyword.toLowerCase();
|
|
filtered = filtered.filter(item => {
|
|
return item.alias?.toLowerCase().includes(keyword) ||
|
|
item.name.toLowerCase().includes(keyword) ||
|
|
item.phoneNumber?.includes(keyword) ||
|
|
item.managercompany?.toLowerCase().includes(keyword);
|
|
});
|
|
}
|
|
|
|
// 区域筛选
|
|
if (selectedArea && selectedArea !== '全部') {
|
|
filtered = filtered.filter(item => {
|
|
return item.responsibleArea?.includes(selectedArea);
|
|
});
|
|
}
|
|
|
|
this.setData({
|
|
filteredServices: filtered
|
|
});
|
|
},
|
|
|
|
onChat: function (e) {
|
|
const id = e.currentTarget.dataset.id;
|
|
const service = this.data.customerServices.find(item => item.id === id);
|
|
// 确保使用managerId作为聊天对象的唯一标识符
|
|
const chatUserId = service?.managerId || id;
|
|
wx.navigateTo({
|
|
url: `/pages/chat-detail/index?userId=${chatUserId}&userName=${encodeURIComponent(service?.alias || '')}&phone=${service?.phoneNumber || ''}&isManager=true`
|
|
});
|
|
console.log('跳转到聊天页面:', { chatUserId, userName: service?.alias });
|
|
},
|
|
|
|
onCall: function (e) {
|
|
const phone = e.currentTarget.dataset.phone;
|
|
wx.makePhoneCall({
|
|
phoneNumber: phone,
|
|
success: function () {
|
|
console.log('拨打电话成功');
|
|
},
|
|
fail: function () {
|
|
console.log('拨打电话失败');
|
|
}
|
|
});
|
|
},
|
|
|
|
// 查看客服详情
|
|
onViewDetail: function (e) {
|
|
const id = e.currentTarget.dataset.id;
|
|
wx.navigateTo({
|
|
url: `/pages/customer-service/detail?id=${id}`
|
|
});
|
|
},
|
|
|
|
onBack: function () {
|
|
wx.navigateBack();
|
|
}
|
|
});
|
|
|