|
|
|
@ -5334,8 +5334,9 @@ |
|
|
|
const recentTbody = document.getElementById('recent-customers-table').querySelector('tbody'); |
|
|
|
recentTbody.innerHTML = ''; // 清空现有内容 |
|
|
|
|
|
|
|
// 按时间排序(最新在前),取前5条 |
|
|
|
// 按时间排序(最新在前),取前5条,过滤掉Colleague类型的客户 |
|
|
|
const sortedCustomers = Object.values(customerData) |
|
|
|
.filter(customer => customer.type !== 'Colleague') // 过滤掉Colleague类型的客户 |
|
|
|
.sort((a, b) => (b.id || '').localeCompare(a.id || '')) // 按ID降序排序,处理空值 |
|
|
|
.slice(0, 5); |
|
|
|
|
|
|
|
@ -5350,10 +5351,10 @@ |
|
|
|
row.dataset.id = customer.id; |
|
|
|
|
|
|
|
// 确定按钮文本和类型 |
|
|
|
const followLevels = ['important', 'regular', 'low-value', 'logistics', 'unclassified']; |
|
|
|
const isFollowCustomer = followLevels.includes(customer.level); |
|
|
|
const buttonText = isFollowCustomer ? '跟进' : '详情'; |
|
|
|
const buttonClass = isFollowCustomer ? 'follow-customer' : 'detail-customer'; |
|
|
|
const followLevels = ['important', 'regular', 'low-value', 'logistics', 'unclassified']; |
|
|
|
const isFollowCustomer = followLevels.includes(customer.level) && customer.type !== 'Colleague'; |
|
|
|
const buttonText = isFollowCustomer ? '跟进' : '详情'; |
|
|
|
const buttonClass = isFollowCustomer ? 'follow-customer' : 'detail-customer'; |
|
|
|
|
|
|
|
row.innerHTML = ` |
|
|
|
<td>${customer.company || '-'}</td> |
|
|
|
@ -5394,6 +5395,10 @@ |
|
|
|
* @param {Object} customer - 新增的客户数据 |
|
|
|
*/ |
|
|
|
function updateCustomerTable(customer) { |
|
|
|
// 如果客户类型是Colleague,不显示 |
|
|
|
if (customer.type === 'Colleague') { |
|
|
|
return; |
|
|
|
} |
|
|
|
let level = customer.level; |
|
|
|
|
|
|
|
// 映射客户等级到正确的HTML ID |
|
|
|
@ -5440,7 +5445,7 @@ |
|
|
|
|
|
|
|
// 确定按钮文本和类型 |
|
|
|
const followLevels = ['important', 'regular', 'low-value', 'logistics', 'unclassified']; |
|
|
|
const isFollowCustomer = followLevels.includes(customer.level); |
|
|
|
const isFollowCustomer = followLevels.includes(customer.level) && customer.type !== 'Colleague'; |
|
|
|
const buttonText = isFollowCustomer ? '跟进' : '详情'; |
|
|
|
const buttonClass = isFollowCustomer ? 'follow-customer' : 'detail-customer'; |
|
|
|
|
|
|
|
@ -5719,9 +5724,43 @@ |
|
|
|
const typeMap = { |
|
|
|
'seller': '供应商', |
|
|
|
'buyer': '客户', |
|
|
|
'both': 'both' |
|
|
|
'both': 'both', |
|
|
|
'Colleague': '同事' |
|
|
|
}; |
|
|
|
document.getElementById('detail-type').textContent = typeMap[customer.type] || customer.type || "-"; |
|
|
|
|
|
|
|
// 当客户类型为Colleague时,不显示隐藏相关的所有内容 |
|
|
|
if (customer.type === 'Colleague') { |
|
|
|
// 隐藏跟进相关的所有内容 |
|
|
|
const followUpElements = document.querySelectorAll('.follow-up-related, .follow-up-section'); |
|
|
|
followUpElements.forEach(el => el.style.display = 'none'); |
|
|
|
|
|
|
|
// 隐藏编辑按钮(同事不需要编辑) |
|
|
|
const editSaveBtn = document.getElementById('editSaveBtn'); |
|
|
|
if (editSaveBtn) { |
|
|
|
editSaveBtn.style.display = 'none'; |
|
|
|
} |
|
|
|
|
|
|
|
// 隐藏其他不需要的内容 |
|
|
|
const addDetailBtn = document.getElementById('addDetailBtn'); |
|
|
|
if (addDetailBtn) { |
|
|
|
addDetailBtn.style.display = 'none'; |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 恢复正常显示 |
|
|
|
const followUpElements = document.querySelectorAll('.follow-up-related, .follow-up-section'); |
|
|
|
followUpElements.forEach(el => el.style.display = ''); |
|
|
|
|
|
|
|
const editSaveBtn = document.getElementById('editSaveBtn'); |
|
|
|
if (editSaveBtn) { |
|
|
|
editSaveBtn.style.display = ''; |
|
|
|
} |
|
|
|
|
|
|
|
const addDetailBtn = document.getElementById('addDetailBtn'); |
|
|
|
if (addDetailBtn) { |
|
|
|
addDetailBtn.style.display = ''; |
|
|
|
} |
|
|
|
} |
|
|
|
document.getElementById('detail-demand').textContent = customer.demand || "-"; |
|
|
|
document.getElementById('detail-spec').textContent = customer.spec || "-"; |
|
|
|
document.getElementById('detail-manager').textContent = customer.userName || "-"; |
|
|
|
@ -6774,99 +6813,130 @@ |
|
|
|
function initWebSocket() { |
|
|
|
console.log('初始化WebSocket连接...'); |
|
|
|
|
|
|
|
// 创建SockJS连接 |
|
|
|
const socket = new SockJS('/DL/ws'); |
|
|
|
// 创建STOMP客户端 |
|
|
|
stompClient = Stomp.over(socket); |
|
|
|
// 检查SockJS和Stomp是否可用 |
|
|
|
if (typeof SockJS === 'undefined' || typeof Stomp === 'undefined') { |
|
|
|
console.warn('WebSocket库加载失败,跳过WebSocket初始化'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
// 创建SockJS连接 |
|
|
|
const socket = new SockJS('/DL/ws'); |
|
|
|
// 创建STOMP客户端 |
|
|
|
stompClient = Stomp.over(socket); |
|
|
|
|
|
|
|
// 设置连接错误处理 |
|
|
|
socket.onerror = function(error) { |
|
|
|
console.error('WebSocket连接错误:', error); |
|
|
|
}; |
|
|
|
|
|
|
|
// 设置连接关闭处理 |
|
|
|
socket.onclose = function(event) { |
|
|
|
console.log('WebSocket连接关闭:', event); |
|
|
|
}; |
|
|
|
|
|
|
|
// 连接到服务器 |
|
|
|
stompClient.connect({}, function(frame) { |
|
|
|
console.log('已连接到WebSocket服务器: ' + frame); |
|
|
|
|
|
|
|
// 获取登录信息,只声明一次 |
|
|
|
const loginInfo = getLoginInfo(); |
|
|
|
|
|
|
|
// 订阅部门公海池主题(带seller角色) |
|
|
|
stompClient.subscribe('/topic/departmentSeaPool/seller', function(response) { |
|
|
|
const customers = JSON.parse(response.body); |
|
|
|
console.log('收到部门公海池数据:', customers); |
|
|
|
|
|
|
|
// 过滤出type为seller或both的客户,并且是部门公海池客户 |
|
|
|
const filteredCustomers = customers.filter(customer => |
|
|
|
(customer.type === 'seller' || customer.type === 'both') && |
|
|
|
(customer.level === 'department-sea-pools') |
|
|
|
); |
|
|
|
try { |
|
|
|
// 获取登录信息,只声明一次 |
|
|
|
const loginInfo = getLoginInfo(); |
|
|
|
|
|
|
|
// 订阅部门公海池主题(带seller角色) |
|
|
|
stompClient.subscribe('/topic/departmentSeaPool/seller', function(response) { |
|
|
|
try { |
|
|
|
const customers = JSON.parse(response.body); |
|
|
|
console.log('收到部门公海池数据:', customers); |
|
|
|
|
|
|
|
// 过滤出type为seller或both的客户,并且是部门公海池客户 |
|
|
|
const filteredCustomers = customers.filter(customer => |
|
|
|
(customer.type === 'seller' || customer.type === 'both') && |
|
|
|
(customer.level === 'department-sea-pools') |
|
|
|
); |
|
|
|
|
|
|
|
// 使用登录信息进行第二层过滤 |
|
|
|
const finalFilteredCustomers = filterSeaPoolData(filteredCustomers, loginInfo, 'department'); |
|
|
|
|
|
|
|
// 存储部门公海池客户到customerData对象,以便查看详情 |
|
|
|
finalFilteredCustomers.forEach(customer => { |
|
|
|
// 确保客户数据包含必要字段 |
|
|
|
if (customer.notice === undefined || customer.notice === null) { |
|
|
|
customer.notice = 'old'; // 默认设置为老客户 |
|
|
|
} |
|
|
|
if (!customer.dataSource) { |
|
|
|
customer.dataSource = 'wechat'; // 默认设置为wechat数据源 |
|
|
|
} |
|
|
|
customerData[customer.id] = customer; |
|
|
|
}); |
|
|
|
|
|
|
|
// 使用登录信息进行第二层过滤 |
|
|
|
const finalFilteredCustomers = filterSeaPoolData(filteredCustomers, loginInfo, 'department'); |
|
|
|
// 更新全局部门公海池数据 |
|
|
|
departmentSeaPoolData = finalFilteredCustomers; |
|
|
|
|
|
|
|
// 存储部门公海池客户到customerData对象,以便查看详情 |
|
|
|
finalFilteredCustomers.forEach(customer => { |
|
|
|
// 确保客户数据包含必要字段 |
|
|
|
if (customer.notice === undefined || customer.notice === null) { |
|
|
|
customer.notice = 'old'; // 默认设置为老客户 |
|
|
|
} |
|
|
|
if (!customer.dataSource) { |
|
|
|
customer.dataSource = 'wechat'; // 默认设置为wechat数据源 |
|
|
|
renderDepartmentSeaPool(finalFilteredCustomers); |
|
|
|
} catch (error) { |
|
|
|
console.error('处理部门公海池数据时出错:', error); |
|
|
|
} |
|
|
|
customerData[customer.id] = customer; |
|
|
|
}); |
|
|
|
|
|
|
|
// 更新全局部门公海池数据 |
|
|
|
departmentSeaPoolData = finalFilteredCustomers; |
|
|
|
|
|
|
|
renderDepartmentSeaPool(finalFilteredCustomers); |
|
|
|
}); |
|
|
|
|
|
|
|
// 订阅组织公海池主题(带seller角色) |
|
|
|
stompClient.subscribe('/topic/organizationSeaPool/seller', function(response) { |
|
|
|
const customers = JSON.parse(response.body); |
|
|
|
console.log('收到组织公海池数据:', customers); |
|
|
|
|
|
|
|
// 过滤出type为seller或both的客户,并且是组织公海池客户 |
|
|
|
const filteredCustomers = customers.filter(customer => |
|
|
|
(customer.type === 'seller' || customer.type === 'both') && |
|
|
|
(customer.level === 'organization-sea-pools') |
|
|
|
); |
|
|
|
// 订阅组织公海池主题(带seller角色) |
|
|
|
stompClient.subscribe('/topic/organizationSeaPool/seller', function(response) { |
|
|
|
try { |
|
|
|
const customers = JSON.parse(response.body); |
|
|
|
console.log('收到组织公海池数据:', customers); |
|
|
|
|
|
|
|
// 过滤出type为seller或both的客户,并且是组织公海池客户 |
|
|
|
const filteredCustomers = customers.filter(customer => |
|
|
|
(customer.type === 'seller' || customer.type === 'both') && |
|
|
|
(customer.level === 'organization-sea-pools') |
|
|
|
); |
|
|
|
|
|
|
|
// 使用登录信息进行第二层过滤 |
|
|
|
const finalFilteredCustomers = filterSeaPoolData(filteredCustomers, loginInfo, 'organization'); |
|
|
|
|
|
|
|
// 存储组织公海池客户到customerData对象,以便查看详情 |
|
|
|
finalFilteredCustomers.forEach(customer => { |
|
|
|
// 确保客户数据包含必要字段 |
|
|
|
if (customer.notice === undefined || customer.notice === null) { |
|
|
|
customer.notice = 'old'; // 默认设置为老客户 |
|
|
|
} |
|
|
|
if (!customer.dataSource) { |
|
|
|
customer.dataSource = 'wechat'; // 默认设置为wechat数据源 |
|
|
|
} |
|
|
|
customerData[customer.id] = customer; |
|
|
|
}); |
|
|
|
|
|
|
|
// 使用登录信息进行第二层过滤 |
|
|
|
const finalFilteredCustomers = filterSeaPoolData(filteredCustomers, loginInfo, 'organization'); |
|
|
|
// 更新全局组织公海池数据 |
|
|
|
organizationSeaPoolData = finalFilteredCustomers; |
|
|
|
|
|
|
|
// 存储组织公海池客户到customerData对象,以便查看详情 |
|
|
|
finalFilteredCustomers.forEach(customer => { |
|
|
|
// 确保客户数据包含必要字段 |
|
|
|
if (customer.notice === undefined || customer.notice === null) { |
|
|
|
customer.notice = 'old'; // 默认设置为老客户 |
|
|
|
renderOrganizationSeaPool(finalFilteredCustomers); |
|
|
|
} catch (error) { |
|
|
|
console.error('处理组织公海池数据时出错:', error); |
|
|
|
} |
|
|
|
if (!customer.dataSource) { |
|
|
|
customer.dataSource = 'wechat'; // 默认设置为wechat数据源 |
|
|
|
} |
|
|
|
customerData[customer.id] = customer; |
|
|
|
}); |
|
|
|
|
|
|
|
// 更新全局组织公海池数据 |
|
|
|
organizationSeaPoolData = finalFilteredCustomers; |
|
|
|
|
|
|
|
renderOrganizationSeaPool(finalFilteredCustomers); |
|
|
|
}); |
|
|
|
|
|
|
|
// 订阅seller角色数据(supply.html页面显示seller类型客户) |
|
|
|
stompClient.subscribe('/topic/role/seller', function(response) { |
|
|
|
const customers = JSON.parse(response.body); |
|
|
|
console.log('收到seller角色数据:', customers); |
|
|
|
// 订阅seller角色数据(supply.html页面显示seller类型客户) |
|
|
|
stompClient.subscribe('/topic/role/seller', function(response) { |
|
|
|
try { |
|
|
|
const customers = JSON.parse(response.body); |
|
|
|
console.log('收到seller角色数据:', customers); |
|
|
|
|
|
|
|
console.log('当前登录用户信息:', loginInfo); |
|
|
|
console.log('当前登录用户信息:', loginInfo); |
|
|
|
|
|
|
|
// 过滤出负责人是当前登录用户的客户 |
|
|
|
let filteredCustomers = customers.filter(customer => |
|
|
|
customer.userName === loginInfo.userName |
|
|
|
); |
|
|
|
// 过滤出负责人是当前登录用户的客户 |
|
|
|
let filteredCustomers = customers.filter(customer => |
|
|
|
customer.userName === loginInfo.userName |
|
|
|
); |
|
|
|
|
|
|
|
console.log('过滤后的客户数据:', filteredCustomers); |
|
|
|
console.log('过滤后的客户数据:', filteredCustomers); |
|
|
|
|
|
|
|
// 更新客户数据 - 以客户ID为键 |
|
|
|
// 更新客户数据 - 以客户ID为键,过滤掉Colleague类型的客户 |
|
|
|
const newCustomerData = {}; |
|
|
|
filteredCustomers.forEach(customer => { |
|
|
|
// 过滤掉Colleague类型的客户 |
|
|
|
if (customer.type === 'Colleague') { |
|
|
|
return; |
|
|
|
} |
|
|
|
// 确保客户数据包含notice字段和dataSource字段 |
|
|
|
if (customer.notice === undefined || customer.notice === null) { |
|
|
|
customer.notice = 'old'; // 默认设置为老客户 |
|
|
|
@ -6879,71 +6949,80 @@ |
|
|
|
}); |
|
|
|
customerData = newCustomerData; |
|
|
|
|
|
|
|
// 更新通知数据 |
|
|
|
getNewCustomers(); |
|
|
|
|
|
|
|
// 更新页面显示 |
|
|
|
updateStatsCards(); |
|
|
|
updateRecentCustomers(); |
|
|
|
// 更新通知数据 |
|
|
|
getNewCustomers(); |
|
|
|
|
|
|
|
// 收集所有唯一的客户等级 |
|
|
|
const customerList = Object.values(customerData); |
|
|
|
const levels = [...new Set(customerList.map(customer => customer.level || 'unclassified'))]; |
|
|
|
// 更新页面显示 |
|
|
|
updateStatsCards(); |
|
|
|
updateRecentCustomers(); |
|
|
|
|
|
|
|
// 清空所有等级的客户表格 |
|
|
|
const allLevels = ['important', 'regular', 'low-value', 'logistics', 'unclassified', 'department-sea-pools', 'organization-sea-pools']; |
|
|
|
allLevels.forEach(level => { |
|
|
|
const tbody = document.getElementById(`${level}-customers`); |
|
|
|
if (tbody) { |
|
|
|
tbody.innerHTML = ''; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 重新渲染所有客户 |
|
|
|
customerList.forEach(customer => { |
|
|
|
updateCustomerTable(customer); |
|
|
|
}); |
|
|
|
// 收集所有唯一的客户等级 |
|
|
|
const customerList = Object.values(customerData); |
|
|
|
const levels = [...new Set(customerList.map(customer => customer.level || 'unclassified'))]; |
|
|
|
|
|
|
|
// 检查每个等级的tbody,如果没有数据且当前不是全部客户视图,则添加"暂无数据"提示 |
|
|
|
const currentLevel = document.querySelector('.level-tab.active').dataset.level; |
|
|
|
allLevels.forEach(level => { |
|
|
|
const tbody = document.getElementById(`${level}-customers`); |
|
|
|
if (tbody && tbody.children.length === 0) { |
|
|
|
if (currentLevel === 'all') { |
|
|
|
// 全部客户视图,隐藏没有数据的等级 |
|
|
|
tbody.innerHTML = ''; |
|
|
|
} else { |
|
|
|
// 非全部客户视图,显示"暂无数据"提示 |
|
|
|
const noDataText = { |
|
|
|
'important': '暂无重要客户数据', |
|
|
|
'regular': '暂无普通客户数据', |
|
|
|
'low-value': '暂无低价值客户数据', |
|
|
|
'logistics': '暂无物流客户数据', |
|
|
|
'unclassified': '暂无未分级客户数据', |
|
|
|
'department-sea-pools': '暂无部门公海客户数据', |
|
|
|
'organization-sea-pools': '暂无组织公海客户数据' |
|
|
|
}[level] || '暂无客户数据'; |
|
|
|
tbody.innerHTML = `<tr><td colspan="9" style="text-align: center; color: #666;">${noDataText}</td></tr>`; |
|
|
|
// 清空所有等级的客户表格 |
|
|
|
const allLevels = ['important', 'regular', 'low-value', 'logistics', 'unclassified', 'department-sea-pools', 'organization-sea-pools']; |
|
|
|
allLevels.forEach(level => { |
|
|
|
const tbody = document.getElementById(`${level}-customers`); |
|
|
|
if (tbody) { |
|
|
|
tbody.innerHTML = ''; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 重新渲染所有客户 |
|
|
|
customerList.forEach(customer => { |
|
|
|
updateCustomerTable(customer); |
|
|
|
}); |
|
|
|
|
|
|
|
// 检查每个等级的tbody,如果没有数据且当前不是全部客户视图,则添加"暂无数据"提示 |
|
|
|
const currentLevel = document.querySelector('.level-tab.active').dataset.level; |
|
|
|
allLevels.forEach(level => { |
|
|
|
const tbody = document.getElementById(`${level}-customers`); |
|
|
|
if (tbody && tbody.children.length === 0) { |
|
|
|
if (currentLevel === 'all') { |
|
|
|
// 全部客户视图,隐藏没有数据的等级 |
|
|
|
tbody.innerHTML = ''; |
|
|
|
} else { |
|
|
|
// 非全部客户视图,显示"暂无数据"提示 |
|
|
|
const noDataText = { |
|
|
|
'important': '暂无重要客户数据', |
|
|
|
'regular': '暂无普通客户数据', |
|
|
|
'low-value': '暂无低价值客户数据', |
|
|
|
'logistics': '暂无物流客户数据', |
|
|
|
'unclassified': '暂无未分级客户数据', |
|
|
|
'department-sea-pools': '暂无部门公海客户数据', |
|
|
|
'organization-sea-pools': '暂无组织公海客户数据' |
|
|
|
}[level] || '暂无客户数据'; |
|
|
|
tbody.innerHTML = `<tr><td colspan="9" style="text-align: center; color: #666;">${noDataText}</td></tr>`; |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} catch (error) { |
|
|
|
console.error('处理seller角色数据时出错:', error); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
console.log('发送登录信息获取数据:', loginInfo); |
|
|
|
console.log('发送登录信息获取数据:', loginInfo); |
|
|
|
|
|
|
|
// 请求部门公海池数据 |
|
|
|
// 发送部门公海池数据请求 - 传入seller角色 |
|
|
|
stompClient.send("/app/customer/departmentSeaPool/seller", {}, JSON.stringify(loginInfo)); |
|
|
|
// 请求部门公海池数据 |
|
|
|
// 发送部门公海池数据请求 - 传入seller角色 |
|
|
|
stompClient.send("/app/customer/departmentSeaPool/seller", {}, JSON.stringify(loginInfo)); |
|
|
|
|
|
|
|
// 发送组织公海池数据请求 - 传入seller角色 |
|
|
|
stompClient.send("/app/customer/organizationSeaPool/seller", {}, JSON.stringify(loginInfo)); |
|
|
|
// 请求seller角色数据 |
|
|
|
stompClient.send("/app/customer/role/seller", {}, JSON.stringify(loginInfo)); |
|
|
|
// 发送组织公海池数据请求 - 传入seller角色 |
|
|
|
stompClient.send("/app/customer/organizationSeaPool/seller", {}, JSON.stringify(loginInfo)); |
|
|
|
// 请求seller角色数据 |
|
|
|
stompClient.send("/app/customer/role/seller", {}, JSON.stringify(loginInfo)); |
|
|
|
} catch (error) { |
|
|
|
console.error('处理WebSocket连接成功后的逻辑时出错:', error); |
|
|
|
} |
|
|
|
}, function(error) { |
|
|
|
console.error('WebSocket连接失败: ' + error); |
|
|
|
// 尝试重新连接 |
|
|
|
setTimeout(initWebSocket, 5000); |
|
|
|
}); |
|
|
|
} catch (error) { |
|
|
|
console.error('初始化WebSocket时出错:', error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 处理客户数据,按照等级分组 |
|
|
|
|