Browse Source

修复响应时间计算问题,更新字段名匹配API返回值

KH
Trae AI 1 month ago
parent
commit
f1b186ef5f
  1. 9
      web/src/main/java/com/example/web/service/impl/UserServiceImpl.java
  2. 817
      web/src/main/resources/static/index.html
  3. 56
      web/src/main/resources/static/login.html

9
web/src/main/java/com/example/web/service/impl/UserServiceImpl.java

@ -783,6 +783,15 @@ public class UserServiceImpl implements UserService {
}
}
// 计算浏览次数
try {
List<UserTrace> traces = userTraceMapper.getProductTraces(product.getProductId());
productMap.put("viewCount", traces.size());
} catch (Exception e) {
e.printStackTrace();
productMap.put("viewCount", 0);
}
processedProducts.add(productMap);
}

817
web/src/main/resources/static/index.html

@ -10,6 +10,58 @@
box-sizing: border-box;
}
// 后台加载剩余货源数据
function loadRemainingProductsData(userRole, userName, total) {
console.log('开始在后台加载剩余货源数据...');
// 计算需要加载的剩余数据量
var remainingSize = Math.min(1000, total); // 最多加载1000条
// 构建查询参数
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=1&size=' + remainingSize;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
var allProducts = data.products || [];
var totalCount = data.total || 0;
var pages = Math.ceil(totalCount / productsPageSize);
// 更新缓存
setCachedData('products', 'all', {
products: allProducts,
total: totalCount,
pages: pages
});
// 缓存所有页面数据
for (var i = 1; i <= pages && i <= 100; i++) { // 最多缓存100页
var startIndex = (i - 1) * productsPageSize;
var endIndex = startIndex + productsPageSize;
var pageProducts = allProducts.slice(startIndex, endIndex);
setCachedData('products', 'page_' + i + '_size_' + productsPageSize, {
products: pageProducts,
total: totalCount,
pages: pages
});
}
console.log('后台加载剩余货源数据完成,共', allProducts.length, '条数据,分为', pages, '页');
console.log('已缓存', Math.min(pages, 100), '页数据');
} else {
console.error('后台加载剩余货源数据失败:', data.message);
}
} else if (xhr.readyState == 4) {
console.error('后台加载剩余货源数据失败:', xhr.status, xhr.statusText);
}
};
xhr.send();
}
body {
font-family: Arial, sans-serif;
background-color: #f5f7fa;
@ -797,6 +849,8 @@
<th>地区</th>
<th>创建时间</th>
<th>销售负责人</th>
<th>货源状态</th>
<th>浏览次数</th>
<th>创建人</th>
<th>操作</th>
</tr>
@ -905,6 +959,7 @@
var productsTotal = 0;
var productsTotalPages = 0;
var isLoadingAllData = false;
var isLoadingProducts = false;
var currentManagerFilter = null;
var currentFilterTable = 'personal';
var currentPhoneSearch = null;
@ -912,6 +967,90 @@
var currentEndDate = null;
var currentTypeFilter = null;
// 数据缓存对象
var dataCache = {
products: {
all: null, // 所有数据
filtered: {}, // 筛选结果缓存,key为筛选条件字符串
pages: {}, // 分页数据缓存,key为页码
timestamp: 0 // 缓存时间戳
},
personal: {
all: null,
filtered: {},
pages: {},
timestamp: 0
},
public: {
pages: {}, // 分页数据缓存,key为页码
timestamp: 0
}
};
// 缓存有效期(毫秒)
var CACHE_DURATION = 5 * 60 * 1000; // 5分钟
// 防抖函数
function debounce(func, wait) {
var timeout;
return function() {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
}
// 节流函数
function throttle(func, limit) {
var inThrottle;
return function() {
var args = arguments;
var context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(function() {
inThrottle = false;
}, limit);
}
};
}
// 缓存管理函数
function getCachedData(type, key) {
var now = Date.now();
if (dataCache[type] && dataCache[type][key] && (now - dataCache[type].timestamp) < CACHE_DURATION) {
return dataCache[type][key];
}
return null;
}
function setCachedData(type, key, data) {
if (!dataCache[type]) {
dataCache[type] = {};
}
dataCache[type][key] = data;
dataCache[type].timestamp = Date.now();
}
// 防抖版本的筛选和搜索函数
var debouncedFilterProducts = debounce(function() {
productFilters.category = document.getElementById('categoryFilter').value;
productFilters.productName = document.getElementById('productNameFilter').value;
productFilters.yolk = document.getElementById('yolkFilter').value;
productFilters.salesManager = document.getElementById('salesManagerFilter').value;
productFilters.creator = document.getElementById('creatorFilter').value;
applyProductFilters();
}, 300);
var debouncedSearchProducts = debounce(function() {
productFilters.search = document.getElementById('productSearch').value;
applyProductFilters();
}, 300);
function init() {
// 检查URL是否包含登录参数
const urlParams = new URLSearchParams(window.location.search);
@ -944,6 +1083,183 @@
if (userRole === '管理员') {
checkApplyStatus();
}
// 预加载货源浏览数据
preloadProductsData();
// 设置每五分钟更新一次缓存
setInterval(updateProductsCache, 5 * 60 * 1000);
}
// 预加载货源浏览数据
function preloadProductsData() {
console.log('开始预加载货源浏览数据...');
// 设置分页参数,先加载50条数据
var oldPageSize = productsPageSize;
var preloadSize = 50; // 先加载50条数据
productsPage = 1;
var userRole = userInfo.loginInfo.projectName;
var userName = userInfo.loginInfo.userName;
// 构建查询参数
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=' + productsPage + '&size=' + preloadSize;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
// 恢复原来的页面大小
productsPageSize = oldPageSize;
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
var products = data.products || [];
var total = data.total || 0;
var pages = Math.ceil(total / productsPageSize);
// 缓存数据
setCachedData('products', 'all', {
products: products,
total: total,
pages: pages
});
// 将20条数据分为两页,每页10条
var page1Products = products.slice(0, productsPageSize);
var page2Products = products.slice(productsPageSize, productsPageSize * 2);
// 缓存第一页数据(前10条)
setCachedData('products', 'page_1_size_' + productsPageSize, {
products: page1Products,
total: total,
pages: pages
});
// 缓存第二页数据(后10条)
setCachedData('products', 'page_2_size_' + productsPageSize, {
products: page2Products,
total: total,
pages: pages
});
console.log('预加载货源浏览数据完成,共', products.length, '条数据,分为', pages, '页');
console.log('第一页缓存', page1Products.length, '条数据,第二页缓存', page2Products.length, '条数据');
// 后台加载剩余数据并放入缓存
loadRemainingProductsData(userRole, userName, total);
} else {
console.error('预加载货源浏览数据失败:', data.message);
}
} else if (xhr.readyState == 4) {
console.error('预加载货源浏览数据失败:', xhr.status, xhr.statusText);
}
};
xhr.send();
}
// 后台加载剩余货源数据
function loadRemainingProductsData(userRole, userName, total) {
console.log('开始在后台加载剩余货源数据...');
// 计算需要加载的剩余数据量
var remainingSize = Math.min(1000, total); // 最多加载1000条
// 构建查询参数
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=1&size=' + remainingSize;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
var allProducts = data.products || [];
var totalCount = data.total || 0;
var pages = Math.ceil(totalCount / productsPageSize);
// 更新缓存
setCachedData('products', 'all', {
products: allProducts,
total: totalCount,
pages: pages
});
// 缓存所有页面数据
for (var i = 1; i <= pages && i <= 100; i++) { // 最多缓存100页
var startIndex = (i - 1) * productsPageSize;
var endIndex = startIndex + productsPageSize;
var pageProducts = allProducts.slice(startIndex, endIndex);
setCachedData('products', 'page_' + i, {
products: pageProducts,
total: totalCount,
pages: pages
});
}
console.log('后台加载剩余货源数据完成,共', allProducts.length, '条数据,分为', pages, '页');
console.log('已缓存', Math.min(pages, 100), '页数据');
} else {
console.error('后台加载剩余货源数据失败:', data.message);
}
} else if (xhr.readyState == 4) {
console.error('后台加载剩余货源数据失败:', xhr.status, xhr.statusText);
}
};
xhr.send();
}
// 更新货源浏览数据缓存
function updateProductsCache() {
console.log('开始更新货源浏览数据缓存...');
var userRole = userInfo.loginInfo.projectName;
var userName = userInfo.loginInfo.userName;
// 构建查询参数,使用阈值1000条
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=1&size=1000';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
var products = data.products || [];
var total = data.total || 0;
var pages = Math.ceil(total / productsPageSize);
// 更新缓存
setCachedData('products', 'all', {
products: products,
total: total,
pages: pages
});
// 更新第一页缓存
setCachedData('products', 'page_1_size_' + productsPageSize, {
products: products,
total: total,
pages: pages
});
console.log('货源浏览数据缓存更新完成,共', products.length, '条数据');
// 检查当前是否在货源浏览页面,如果是则重新渲染
var activeTab = document.querySelector('.tab.active');
if (activeTab && activeTab.id === 'products') {
displayProducts(products);
}
} else {
console.error('更新货源浏览数据缓存失败:', data.message);
}
} else if (xhr.readyState == 4) {
console.error('更新货源浏览数据缓存失败:', xhr.status, xhr.statusText);
}
};
xhr.send();
}
function loadPersonnelData() {
@ -2114,20 +2430,92 @@
var userRole = userInfo.loginInfo.projectName;
var userName = userInfo.loginInfo.userName;
// 检查是否正在加载
if (isLoadingProducts) return;
isLoadingProducts = true;
// 检查是否有筛选条件
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
// 如果有筛选条件,优先使用缓存中的完整数据
if (hasFilters) {
var cachedAllData = getCachedData('products', 'all');
if (cachedAllData && cachedAllData.products.length > 0) {
console.log('使用缓存中的完整数据进行筛选');
applyProductFilters();
isLoadingProducts = false;
return;
}
}
// 先检查缓存数据
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
if (cachedData) {
console.log('使用缓存数据加载货源,页码:', productsPage, '每页条数:', productsPageSize);
allProducts = cachedData.products || [];
productsTotal = cachedData.total || 0;
productsTotalPages = cachedData.pages || Math.ceil(productsTotal / productsPageSize);
// 显示当前页数据
displayProducts(allProducts);
// 确保使用当前的productsPageSize值渲染分页组件
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
isLoadingProducts = false;
return;
}
// 如果没有对应每页显示条数的缓存数据,尝试使用缓存中的完整数据集
var cachedAllData = getCachedData('products', 'all');
if (cachedAllData && cachedAllData.products.length > 0) {
console.log('使用缓存中的完整数据生成对应每页显示条数的数据');
var allProductsData = cachedAllData.products;
productsTotal = cachedAllData.total || allProductsData.length;
productsTotalPages = Math.ceil(productsTotal / productsPageSize);
// 根据当前页码和每页显示条数计算数据范围
var startIndex = (productsPage - 1) * productsPageSize;
var endIndex = startIndex + productsPageSize;
allProducts = allProductsData.slice(startIndex, endIndex);
// 缓存生成的数据
setCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize, {
products: allProducts,
total: productsTotal,
pages: productsTotalPages
});
// 显示当前页数据
displayProducts(allProducts);
// 确保使用当前的productsPageSize值渲染分页组件
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
isLoadingProducts = false;
return;
}
// 构建查询参数,使用当前页和每页显示条数
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=' + productsPage + '&size=' + productsPageSize;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
isLoadingProducts = false;
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
allProducts = data.products || [];
productsTotal = data.total || 0;
productsTotalPages = data.pages || 0;
displayProducts(data.products);
productsTotalPages = data.pages || Math.ceil(productsTotal / productsPageSize);
// 显示当前页数据
displayProducts(allProducts);
// 确保使用当前的productsPageSize值渲染分页组件
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
// 缓存当前页数据
setCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize, {
products: allProducts,
total: productsTotal,
pages: productsTotalPages
});
} else {
showAlert('加载货源失败: ' + data.message);
}
@ -2139,6 +2527,13 @@
xhr.send();
}
// 获取当前页的产品数据
function getCurrentPageProducts() {
var startIndex = (productsPage - 1) * productsPageSize;
var endIndex = startIndex + productsPageSize;
return allProducts.slice(startIndex, endIndex);
}
// 显示货源数据
function displayProducts(products) {
var productsBody = document.getElementById('productsBody');
@ -2159,6 +2554,8 @@
'<td>' + (product.fullRegion || product.region || '-') + '</td>' +
'<td>' + formatDateTime(product.created_at) + '</td>' +
'<td>' + (product.salesManager || '-') + '</td>' +
'<td>' + ((product.status === 'hidden' || product.status === 'sold_out') ? '已下架' : (product.status === 'published' ? '已上架' : '-')) + '</td>' +
'<td>' + (product.viewCount || 0) + '</td>' +
'<td>' + (product.creator || '-') + '</td>' +
'<td><button onclick="openProductDetailModal(\'' + (product.productId || '') + '\')" style="padding: 4px 8px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 12px;">查看详情</button></td>' +
'</tr>';
@ -2194,21 +2591,14 @@
// 筛选货源
function filterProducts() {
// 获取筛选值
productFilters.category = document.getElementById('categoryFilter').value;
productFilters.productName = document.getElementById('productNameFilter').value;
productFilters.yolk = document.getElementById('yolkFilter').value;
productFilters.salesManager = document.getElementById('salesManagerFilter').value;
productFilters.creator = document.getElementById('creatorFilter').value;
// 应用筛选
applyProductFilters();
// 使用防抖版本的筛选函数
debouncedFilterProducts();
}
// 搜索货源
function searchProducts() {
productFilters.search = document.getElementById('productSearch').value;
applyProductFilters();
// 使用防抖版本的搜索函数
debouncedSearchProducts();
}
// 重置货源筛选
@ -2237,14 +2627,18 @@
// 应用货源筛选
function applyProductFilters() {
if (allProducts.length === 0) {
// 优先使用缓存中的完整数据
var cachedAllData = getCachedData('products', 'all');
var sourceProducts = cachedAllData ? cachedAllData.products : allProducts;
if (sourceProducts.length === 0) {
// 如果还没有数据,先加载
loadProducts();
return;
}
// 应用筛选
var filteredProducts = allProducts.filter(product => {
var filteredProducts = sourceProducts.filter(product => {
// 种类筛选
if (productFilters.category && product.category !== productFilters.category) {
return false;
@ -2283,12 +2677,25 @@
return true;
});
// 显示筛选结果
displayProducts(filteredProducts);
// 计算筛选后的总页数
var filteredTotal = filteredProducts.length;
var filteredTotalPages = Math.ceil(filteredTotal / productsPageSize);
// 重新渲染分页(筛选后的数据可能更少)
var totalPages = Math.ceil(filteredProducts.length / productsPageSize);
renderProductsPagination(1, totalPages, filteredProducts.length);
// 确保当前页码不超过总页数
if (productsPage > filteredTotalPages) {
productsPage = Math.max(1, filteredTotalPages);
}
// 显示当前页的筛选结果
var startIndex = (productsPage - 1) * productsPageSize;
var endIndex = startIndex + productsPageSize;
var currentPageProducts = filteredProducts.slice(startIndex, endIndex);
// 显示数据
displayProducts(currentPageProducts);
// 重新渲染分页
renderProductsPagination(productsPage, filteredTotalPages, filteredTotal);
}
// 显示商品详情
@ -2315,6 +2722,74 @@
// 将分组后的数据转换为数组
var mergedTraces = Object.values(groupedTraces);
// 计算响应时间:跟进时间减去创建时间
mergedTraces.forEach(trace => {
if (trace.phoneNumber) {
// 根据电话号码获取用户信息
var url = '/KH/api/users/public?phoneNumber=' + encodeURIComponent(trace.phoneNumber) + '&userRole=admin';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.users && data.users.length > 0) {
var user = data.users[0];
var createTime = user.create_time;
var followupTime = user.followup_time;
if (createTime && followupTime) {
// 计算响应时间
var createDate = new Date(createTime);
var followupDate = new Date(followupTime);
var responseTimeMs = followupDate - createDate;
// 转换为人类可读的格式
var minutes = Math.floor(responseTimeMs / 60000);
var hours = Math.floor(minutes / 60);
var days = Math.floor(hours / 24);
var responseTimeStr = '';
if (days > 0) {
responseTimeStr += days + '天';
}
if (hours % 24 > 0) {
responseTimeStr += (hours % 24) + '小时';
}
if (minutes % 60 > 0) {
responseTimeStr += (minutes % 60) + '分钟';
}
if (responseTimeStr) {
trace.responseTime = responseTimeStr;
// 更新页面上的响应时间
var tables = document.querySelectorAll('table');
tables.forEach(table => {
var header = table.querySelector('th');
if (header && header.textContent === '昵称') {
var tbody = table.querySelector('tbody');
if (tbody) {
var rows = tbody.querySelectorAll('tr');
rows.forEach((row) => {
var phoneCell = row.querySelector('td:nth-child(2)');
if (phoneCell && phoneCell.textContent.trim() === trace.phoneNumber) {
var responseCell = row.querySelector('td:nth-child(5)');
if (responseCell) {
responseCell.textContent = responseTimeStr;
}
}
});
}
}
});
}
}
}
}
};
xhr.send();
}
});
// 检查是否为管理员
var isAdmin = userInfo && userInfo.loginInfo && userInfo.loginInfo.projectName === '管理员';
@ -2441,6 +2916,77 @@
// 加载申请状态并更新按钮
loadApplyStatusForTraces(mergedTraces);
// 弹窗创建完成后,调用函数计算响应时间
calculateResponseTimes(mergedTraces);
// 弹窗创建完成后,计算响应时间:跟进时间减去创建时间
mergedTraces.forEach(trace => {
if (trace.phoneNumber) {
// 根据电话号码获取用户信息
var url = '/KH/api/users/public?phoneNumber=' + encodeURIComponent(trace.phoneNumber) + '&userRole=admin';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.users && data.users.length > 0) {
var user = data.users[0];
var createTime = user.create_time;
var followupTime = user.followup_time;
if (createTime && followupTime) {
// 计算响应时间
var createDate = new Date(createTime);
var followupDate = new Date(followupTime);
var responseTimeMs = followupDate - createDate;
// 转换为人类可读的格式
var minutes = Math.floor(responseTimeMs / 60000);
var hours = Math.floor(minutes / 60);
var days = Math.floor(hours / 24);
var responseTimeStr = '';
if (days > 0) {
responseTimeStr += days + '天';
}
if (hours % 24 > 0) {
responseTimeStr += (hours % 24) + '小时';
}
if (minutes % 60 > 0) {
responseTimeStr += (minutes % 60) + '分钟';
}
if (responseTimeStr) {
trace.responseTime = responseTimeStr;
// 更新页面上的响应时间
var tables = document.querySelectorAll('table');
tables.forEach(table => {
var header = table.querySelector('th');
if (header && header.textContent === '昵称') {
var tbody = table.querySelector('tbody');
if (tbody) {
var rows = tbody.querySelectorAll('tr');
rows.forEach((row) => {
var phoneCell = row.querySelector('td:nth-child(2)');
if (phoneCell && phoneCell.textContent.trim() === trace.phoneNumber) {
var responseCell = row.querySelector('td:nth-child(5)');
if (responseCell) {
responseCell.textContent = responseTimeStr;
}
}
});
}
}
});
}
}
}
}
};
xhr.send();
}
});
}
// 加载浏览记录中客户的申请状态
@ -2683,8 +3229,12 @@
// 当总页数大于1时显示分页组件
// 或者当用户选择的每页显示条数不等于默认值时也显示分页组件
// 或者当用户进行了筛选或搜索时也显示分页组件
var defaultPageSize = 10;
if (totalPages <= 1 && totalItems <= productsPageSize && productsPageSize === defaultPageSize) {
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
if (totalPages <= 1 && totalItems <= productsPageSize && productsPageSize === defaultPageSize && !hasFilters) {
paginationContainer.style.display = 'none';
return;
}
@ -2696,8 +3246,29 @@
firstButton.onclick = function() {
if (productsPage > 1) {
productsPage = 1;
// 检查是否有筛选条件
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
if (hasFilters) {
// 如果有筛选条件,重新应用筛选
applyProductFilters();
} else {
// 检查缓存
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
if (cachedData) {
// 使用缓存数据
allProducts = cachedData.products || [];
productsTotal = cachedData.total || 0;
productsTotalPages = cachedData.pages || totalPages;
displayProducts(allProducts);
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
} else {
// 如果没有缓存,重新加载数据
loadProducts();
}
}
}
};
paginationContainer.appendChild(firstButton);
@ -2708,8 +3279,29 @@
prevButton.onclick = function() {
if (productsPage > 1) {
productsPage = productsPage - 1;
// 检查是否有筛选条件
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
if (hasFilters) {
// 如果有筛选条件,重新应用筛选
applyProductFilters();
} else {
// 检查缓存
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
if (cachedData) {
// 使用缓存数据
allProducts = cachedData.products || [];
productsTotal = cachedData.total || 0;
productsTotalPages = cachedData.pages || totalPages;
displayProducts(allProducts);
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
} else {
// 如果没有缓存,重新加载数据
loadProducts();
}
}
}
};
paginationContainer.appendChild(prevButton);
@ -2724,10 +3316,31 @@
nextButton.textContent = '下一页';
nextButton.disabled = currentPage === totalPages;
nextButton.onclick = function() {
if (productsPage < productsTotalPages) {
if (productsPage < totalPages) {
productsPage = productsPage + 1;
// 检查是否有筛选条件
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
if (hasFilters) {
// 如果有筛选条件,重新应用筛选
applyProductFilters();
} else {
// 检查缓存
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
if (cachedData) {
// 使用缓存数据
allProducts = cachedData.products || [];
productsTotal = cachedData.total || 0;
productsTotalPages = cachedData.pages || totalPages;
displayProducts(allProducts);
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
} else {
// 如果没有缓存,重新加载数据
loadProducts();
}
}
}
};
paginationContainer.appendChild(nextButton);
@ -2736,10 +3349,31 @@
lastButton.textContent = '末页';
lastButton.disabled = currentPage === totalPages;
lastButton.onclick = function() {
if (productsPage < productsTotalPages) {
productsPage = productsTotalPages;
if (productsPage < totalPages) {
productsPage = totalPages;
// 检查是否有筛选条件
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
if (hasFilters) {
// 如果有筛选条件,重新应用筛选
applyProductFilters();
} else {
// 检查缓存
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
if (cachedData) {
// 使用缓存数据
allProducts = cachedData.products || [];
productsTotal = cachedData.total || 0;
productsTotalPages = cachedData.pages || totalPages;
displayProducts(allProducts);
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
} else {
// 如果没有缓存,重新加载数据
loadProducts();
}
}
}
};
paginationContainer.appendChild(lastButton);
@ -2774,7 +3408,18 @@
productsPageSize = selectedSize;
console.log('Updated productsPageSize to:', productsPageSize);
productsPage = 1; // 重置为第一页
// 检查是否有筛选条件
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
if (hasFilters) {
// 如果有筛选条件,重新应用筛选
applyProductFilters();
} else {
// 否则重新加载数据
loadProducts();
}
};
})(pageSizeSelect);
paginationContainer.appendChild(pageSizeSelect);
@ -2801,9 +3446,18 @@
var jumpInputElement = document.querySelector('#productsPagination input[type="number"]');
if (jumpInputElement) {
var jumpPage = parseInt(jumpInputElement.value);
if (jumpPage >= 1 && jumpPage <= productsTotalPages) {
if (jumpPage >= 1 && jumpPage <= totalPages) {
productsPage = jumpPage;
// 检查是否有筛选条件
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
productFilters.salesManager || productFilters.creator || productFilters.search;
if (hasFilters) {
// 如果有筛选条件,重新应用筛选
applyProductFilters();
} else {
// 如果没有筛选条件,重新加载数据
loadProducts();
}
} else {
showAlert('请输入有效的页码');
}
@ -5890,6 +6544,119 @@
window.onload = function() {
init();
};
// 计算响应时间的函数
function calculateResponseTimes(traces) {
console.log('开始计算响应时间,traces长度:', traces.length);
traces.forEach(trace => {
console.log('处理trace:', trace);
if (trace.phoneNumber) {
console.log('处理电话号码:', trace.phoneNumber);
// 根据电话号码获取用户信息
var url = '/KH/api/users/public?phoneNumber=' + encodeURIComponent(trace.phoneNumber) + '&userRole=admin';
console.log('API请求URL:', url);
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
console.log('API请求状态:', xhr.readyState, xhr.status);
if (xhr.readyState == 4) {
if (xhr.status == 200) {
try {
var data = JSON.parse(xhr.responseText);
console.log('API响应数据:', data);
if (data.users && data.users.length > 0) {
var user = data.users[0];
console.log('用户信息:', user);
var createTime = user.created_at;
var followupTime = user.followup_at;
console.log('创建时间:', createTime, '跟进时间:', followupTime);
if (createTime && followupTime) {
// 计算响应时间
var createDate = new Date(createTime);
var followupDate = new Date(followupTime);
console.log('创建日期:', createDate, '跟进日期:', followupDate);
var responseTimeMs = followupDate - createDate;
console.log('响应时间毫秒:', responseTimeMs);
// 转换为人类可读的格式
var minutes = Math.floor(responseTimeMs / 60000);
var hours = Math.floor(minutes / 60);
var days = Math.floor(hours / 24);
var responseTimeStr = '';
if (days > 0) {
responseTimeStr += days + '天';
}
if (hours % 24 > 0) {
responseTimeStr += (hours % 24) + '小时';
}
if (minutes % 60 > 0) {
responseTimeStr += (minutes % 60) + '分钟';
}
console.log('响应时间字符串:', responseTimeStr);
if (responseTimeStr) {
trace.responseTime = responseTimeStr;
// 更新页面上的响应时间
var tables = document.querySelectorAll('table');
console.log('找到表格数量:', tables.length);
tables.forEach(table => {
var header = table.querySelector('th');
if (header) {
console.log('表格标题:', header.textContent);
if (header.textContent === '昵称') {
var tbody = table.querySelector('tbody');
if (tbody) {
var rows = tbody.querySelectorAll('tr');
console.log('找到行数量:', rows.length);
rows.forEach((row, index) => {
console.log('处理行:', index);
var cells = row.querySelectorAll('td');
if (cells.length >= 5) {
var phoneCell = cells[1]; // 第二列是手机号
console.log('手机号单元格内容:', phoneCell.textContent.trim(), '预期:', trace.phoneNumber);
if (phoneCell.textContent.trim() === trace.phoneNumber) {
var responseCell = cells[4]; // 第五列是响应时间
console.log('更新响应时间单元格:', responseTimeStr);
responseCell.textContent = responseTimeStr;
console.log('更新后单元格内容:', responseCell.textContent);
}
} else {
console.log('行单元格数量不足:', cells.length);
}
});
} else {
console.log('表格体未找到');
}
}
} else {
console.log('表格标题未找到');
}
});
}
} else {
console.log('创建时间或跟进时间不存在');
}
} else {
console.log('API响应中没有用户数据');
}
} catch (e) {
console.log('解析JSON失败:', e);
}
} else {
console.log('API请求失败,状态码:', xhr.status);
console.log('API响应内容:', xhr.responseText);
}
}
};
xhr.send();
} else {
console.log('电话号码不存在:', trace);
}
});
}
</script>
</body>
</html>

56
web/src/main/resources/static/login.html

@ -234,7 +234,7 @@
console.log('登录API响应数据:', data);
if (data.success) {
// 登录成功,存储用户信息并跳转到主页面
// 登录成功,存储用户信息
console.log('登录成功,准备存储用户信息...');
localStorage.setItem('userInfo', JSON.stringify(data));
console.log('用户信息已存储,localStorage内容:', localStorage.getItem('userInfo'));
@ -243,9 +243,61 @@
localStorage.removeItem('autoLoginInfo');
localStorage.removeItem('proxyLoginInfo'); // 新增:清除代理登录信息
// 添加加载动画
console.log('显示加载动画...');
const loadingOverlay = document.createElement('div');
loadingOverlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.9);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9999;
font-family: Arial, sans-serif;
`;
const loadingSpinner = document.createElement('div');
loadingSpinner.style.cssText = `
border: 4px solid rgba(24, 144, 255, 0.3);
border-radius: 50%;
border-top: 4px solid #1890ff;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin-bottom: 20px;
`;
const loadingText = document.createElement('div');
loadingText.textContent = '加载中,请稍候...';
loadingText.style.cssText = `
font-size: 16px;
color: #333;
`;
const style = document.createElement('style');
style.textContent = `
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
`;
document.head.appendChild(style);
loadingOverlay.appendChild(loadingSpinner);
loadingOverlay.appendChild(loadingText);
document.body.appendChild(loadingOverlay);
// 延迟3秒后跳转到主页面
console.log('准备跳转到index.html...');
setTimeout(() => {
// 优化:使用绝对路径跳转
window.location.href = '/KH/index.html';
}, 3000);
} else {
console.log('登录失败,错误信息:', data.message);
errorMessage.textContent = data.message;
@ -273,7 +325,7 @@
console.log('收到来自其他页面的消息:', event);
// 验证消息来源(可选,增强安全性)
if (event.origin === 'http://8.137.125.67:3005' || event.origin === 'http://8.137.125.67:8083') {
if (event.origin === 'http://localhost:3005' || event.origin === 'http://localhost:8083') {
try {
const messageData = event.data;
if (messageData.type === 'LOGIN_INFO') {

Loading…
Cancel
Save