diff --git a/my-vue-app/src/views/maneger/manager.vue b/my-vue-app/src/views/maneger/manager.vue index aef0fd0..e9a4cf6 100644 --- a/my-vue-app/src/views/maneger/manager.vue +++ b/my-vue-app/src/views/maneger/manager.vue @@ -82,6 +82,51 @@ import { useUserStore } from "@/stores/user"; import { useRouter } from "vue-router"; import {getGroupAbnormalResponse, getWeekTotalCall, getWeekAddCustomerTotal, getWeekAddDealTotal, getWeekAddFeeTotal, getGroupFunnel,getPayDepositToMoneyRate,getGroupRanking } from "@/api/manager.js"; +// 缓存系统 +const cache = new Map() +const CACHE_DURATION = 30 * 60 * 1000 // 30分钟缓存 + +// 缓存工具函数 +function getCacheKey(apiName, params = {}) { + return `${apiName}_${JSON.stringify(params)}` +} + +function isValidCache(cacheData) { + return cacheData && (Date.now() - cacheData.timestamp) < CACHE_DURATION +} + +function setCache(key, data) { + cache.set(key, { + data, + timestamp: Date.now() + }) +} + +function getCache(key) { + const cacheData = cache.get(key) + if (isValidCache(cacheData)) { + return cacheData.data + } + cache.delete(key) + return null +} + +// 通用缓存包装函数 +async function withCache(apiName, apiCall, params = {}) { + const key = getCacheKey(apiName, params) + const cachedData = getCache(key) + + if (cachedData) { + console.log(`使用缓存数据: ${key}`) + return cachedData + } + + console.log(`调用API: ${key}`) + const result = await apiCall() + setCache(key, result) + return result +} + // 团队成员数据 const teamMembers = [ { @@ -152,7 +197,7 @@ async function TeamGetGroupAbnormalResponse() { const params = getRequestParams() const hasParams = params.user_name try { - const response = await getGroupAbnormalResponse(hasParams ? params : undefined) + const response = await withCache('getGroupAbnormalResponse', () => getGroupAbnormalResponse(hasParams ? params : undefined), hasParams ? params : {}) const rawData = response.data // 转换数据格式,生成预警消息 @@ -197,7 +242,7 @@ async function TeamGetGroupAbnormalResponse() { async function TeamGetWeekTotalCall() { const params = getRequestParams() const hasParams = params.user_name - const res = await getWeekTotalCall(hasParams ? params : undefined) + const res = await withCache('getWeekTotalCall', () => getWeekTotalCall(hasParams ? params : undefined), hasParams ? params : {}) console.log(res) if (res.code === 200) { weekTotalData.value.week_total_call = res.data @@ -207,7 +252,7 @@ async function TeamGetWeekTotalCall() { async function TeamGetWeekAddCustomerTotal() { const params = getRequestParams() const hasParams = params.user_name - const res = await getWeekAddCustomerTotal(hasParams ? params : undefined) + const res = await withCache('getWeekAddCustomerTotal', () => getWeekAddCustomerTotal(hasParams ? params : undefined), hasParams ? params : {}) console.log(res) if (res.code === 200) { weekTotalData.value.week_add_customer_total = res.data @@ -217,7 +262,7 @@ async function TeamGetWeekAddCustomerTotal() { async function TeamGetWeekAddDealTotal() { const params = getRequestParams() const hasParams = params.user_name - const res = await getWeekAddDealTotal(hasParams ? params : undefined) + const res = await withCache('getWeekAddDealTotal', () => getWeekAddDealTotal(hasParams ? params : undefined), hasParams ? params : {}) console.log(res) if (res.code === 200) { weekTotalData.value.week_add_deal_total = res.data @@ -230,7 +275,7 @@ async function TeamGetWeekAddDealTotal() { async function TeamGetWeekAddFeeTotal() { const params = getRequestParams() const hasParams = params.user_name - const res = await getPayDepositToMoneyRate(hasParams ? params : undefined) + const res = await withCache('getPayDepositToMoneyRate', () => getPayDepositToMoneyRate(hasParams ? params : undefined), hasParams ? params : {}) console.log(res) if (res.code === 200) { weekTotalData.value.pay_deposit_to_money_rate = res.data @@ -240,7 +285,7 @@ async function TeamGetWeekAddFeeTotal() { async function TeamGetGroupFunnel() { const params = getRequestParams() const hasParams = params.user_name - const res = await getGroupFunnel(hasParams ? params : undefined) + const res = await withCache('getGroupFunnel', () => getGroupFunnel(hasParams ? params : undefined), hasParams ? params : {}) console.log(res) if (res.code === 200) { weekTotalData.value.group_funnel = res.data @@ -265,7 +310,7 @@ const groupRanking = ref({}) async function TeamGetGroupRanking() { const params = getRequestParams() const hasParams = params.user_name - const res = await getGroupRanking(hasParams ? params : undefined) + const res = await withCache('getGroupRanking', () => getGroupRanking(hasParams ? params : undefined), hasParams ? params : {}) console.log(res) if (res.code === 200) { groupRanking.value = res.data @@ -283,16 +328,97 @@ const selectMember = (member) => { selectedMember.value = member; }; +// 缓存管理功能 +// 清除所有缓存 +function clearCache() { + cache.clear() + console.log('所有缓存已清除') +} + +// 清除特定缓存 +function clearSpecificCache(apiName, params = {}) { + const key = getCacheKey(apiName, params) + cache.delete(key) + console.log(`已清除缓存: ${key}`) +} + +// 获取缓存信息并清理过期缓存 +function getCacheInfo() { + const now = Date.now() + const validCaches = [] + const expiredCaches = [] + + for (const [key, data] of cache.entries()) { + if (isValidCache(data)) { + validCaches.push({ + key, + timestamp: data.timestamp, + age: Math.round((now - data.timestamp) / 1000) + 's' + }) + } else { + expiredCaches.push(key) + cache.delete(key) + } + } + + console.log('有效缓存:', validCaches) + console.log('已清理过期缓存:', expiredCaches) + + return { + validCount: validCaches.length, + expiredCount: expiredCaches.length, + validCaches, + expiredCaches + } +} + +// 强制刷新所有数据(清除缓存并重新调用所有API) +async function forceRefreshAllData() { + console.log('开始强制刷新所有数据...') + clearCache() + + // 重新调用所有API + await Promise.all([ + TeamGetGroupAbnormalResponse(), + TeamGetWeekTotalCall(), + TeamGetWeekAddCustomerTotal(), + TeamGetWeekAddDealTotal(), + TeamGetWeekAddFeeTotal(), + TeamGetGroupFunnel(), + TeamGetGroupRanking() + ]) + + console.log('所有数据刷新完成') +} + // 团队异常预警 onMounted(async () => { + // 输出缓存状态信息 + console.log('Manager页面缓存系统已初始化,缓存时长:', CACHE_DURATION / (1000 * 60), '分钟') + await TeamGetGroupAbnormalResponse() - await TeamGetWeekTotalCall() - await TeamGetWeekAddCustomerTotal() - await TeamGetWeekAddDealTotal() - await TeamGetWeekAddFeeTotal() - await TeamGetGroupFunnel() - await TeamGetGroupRanking() + await TeamGetWeekTotalCall() + await TeamGetWeekAddCustomerTotal() + await TeamGetWeekAddDealTotal() + await TeamGetWeekAddFeeTotal() + await TeamGetGroupFunnel() + await TeamGetGroupRanking() + + // 输出初始缓存信息 + getCacheInfo() + + // 开发环境下暴露缓存管理函数到全局对象,方便调试 + if (process.env.NODE_ENV === 'development') { + window.managerCache = { + clearCache, + clearSpecificCache, + getCacheInfo, + forceRefreshAllData, + cache + } + console.log('开发模式:缓存管理函数已暴露到 window.managerCache') + } }) diff --git a/my-vue-app/src/views/person/sale.vue b/my-vue-app/src/views/person/sale.vue index defe17b..6175146 100644 --- a/my-vue-app/src/views/person/sale.vue +++ b/my-vue-app/src/views/person/sale.vue @@ -130,6 +130,63 @@ import {getCustomerAttendance,getTodayCall,getProblemDistribution,getTableFillin getWeeklyActiveCommunicationRate,getTimeoutResponseRate,getCustomerCallInfo,getCustomerChatInfo,getCustomerFormInfo, getConversionRateAndAllocatedData,getCustomerAttendanceAfterClass4,getPayMoneyCustomers,getSalesFunnel,getGoldContactTime} from "@/api/api.js" +// 缓存系统 +const cache = new Map(); +const CACHE_DURATION = 30 * 60 * 1000; // 30分钟缓存时长 + +// 生成缓存键 +const getCacheKey = (apiName, params = {}) => { + const sortedParams = Object.keys(params) + .sort() + .reduce((result, key) => { + result[key] = params[key]; + return result; + }, {}); + return `${apiName}_${JSON.stringify(sortedParams)}`; +}; + +// 检查缓存是否有效 +const isValidCache = (cacheData) => { + return cacheData && (Date.now() - cacheData.timestamp) < CACHE_DURATION; +}; + +// 设置缓存 +const setCache = (key, data) => { + cache.set(key, { + data, + timestamp: Date.now() + }); +}; + +// 获取缓存 +const getCache = (key) => { + const cacheData = cache.get(key); + if (isValidCache(cacheData)) { + return cacheData.data; + } + // 如果缓存过期,删除它 + if (cacheData) { + cache.delete(key); + } + return null; +}; + +// 缓存包装器函数 +const withCache = async (apiName, apiFunction, params = {}) => { + const cacheKey = getCacheKey(apiName, params); + const cachedData = getCache(cacheKey); + + if (cachedData) { + console.log(`[缓存命中] ${apiName}:`, cachedData); + return cachedData; + } + + console.log(`[API调用] ${apiName}`); + const result = await apiFunction(params); + setCache(cacheKey, result); + return result; +}; + // 路由实例 const router = useRouter(); @@ -261,13 +318,13 @@ async function getCoreKpi() { const hasParams = params.user_name // 今日通话数据 - const res = await getTodayCall(hasParams ? params : undefined) + const res = await withCache('getTodayCall', () => getTodayCall(hasParams ? params : undefined), hasParams ? params : {}) if (res.code === 200) { kpiDataState.totalCalls = res.data.today_call } // 转化率、分配数据量、加微率 - const conversionRes = await getConversionRateAndAllocatedData(hasParams ? params : undefined) + const conversionRes = await withCache('getConversionRateAndAllocatedData', () => getConversionRateAndAllocatedData(hasParams ? params : undefined), hasParams ? params : {}) if (conversionRes.code === 200) { kpiDataState.conversionRate = conversionRes.data.conversion_rate || 0 kpiDataState.assignedData = conversionRes.data.all_count || 0 @@ -288,25 +345,25 @@ async function getStatisticsData() { const hasParams = params.user_name // 获取表单填写率 - const fillingRateRes = await getTableFillingRate(hasParams ? params : undefined) + const fillingRateRes = await withCache('getTableFillingRate', () => getTableFillingRate(hasParams ? params : undefined), hasParams ? params : {}) if (fillingRateRes.code === 200) { statisticsData.formCompletionRate = fillingRateRes.data.filling_rate } // 获取平均响应时间 - const avgResponseRes = await getAverageResponseTime(hasParams ? params : undefined) + const avgResponseRes = await withCache('getAverageResponseTime', () => getAverageResponseTime(hasParams ? params : undefined), hasParams ? params : {}) if (avgResponseRes.code === 200) { statisticsData.averageResponseTime = avgResponseRes.data.average_minutes } // 获取客户沟通率 - const communicationRes = await getWeeklyActiveCommunicationRate(hasParams ? params : undefined) + const communicationRes = await withCache('getWeeklyActiveCommunicationRate', () => getWeeklyActiveCommunicationRate(hasParams ? params : undefined), hasParams ? params : {}) if (communicationRes.code === 200) { statisticsData.customerCommunicationRate = communicationRes.data.communication_rate } // 获取超时响应率 - const timeoutRes = await getTimeoutResponseRate(hasParams ? params : undefined) + const timeoutRes = await withCache('getTimeoutResponseRate', () => getTimeoutResponseRate(hasParams ? params : undefined), hasParams ? params : {}) if (timeoutRes.code === 200) { statisticsData.timeoutResponseRate = timeoutRes.data.overtime_rate_600 statisticsData.severeTimeoutRate = timeoutRes.data.overtime_rate_800 @@ -324,7 +381,7 @@ async function getUrgentProblem() { const params = getRequestParams() const hasParams = params.user_name - const res = await getProblemDistribution(hasParams ? params : undefined) + const res = await withCache('getProblemDistribution', () => getProblemDistribution(hasParams ? params : undefined), hasParams ? params : {}) if(res.code === 200) { // 将API返回的对象格式转换为数组格式 const problemDistributionCount = res.data.problem_distribution_count @@ -343,7 +400,7 @@ async function getTimeline() { const params = getRequestParams() const hasParams = params.user_name // 前6个阶段 - const res = await getCustomerAttendance(hasParams ? params : undefined) + const res = await withCache('getCustomerAttendance', () => getCustomerAttendance(hasParams ? params : undefined), hasParams ? params : {}) if(res.code === 200) { // 处理时间线数据 if (res.data.timeline) { @@ -362,7 +419,7 @@ async function getTimeline() { } } // 后4个阶段 - const classRes = await getCustomerAttendanceAfterClass4(hasParams ? params : undefined) + const classRes = await withCache('getCustomerAttendanceAfterClass4', () => getCustomerAttendanceAfterClass4(hasParams ? params : undefined), hasParams ? params : {}) if(classRes.code === 200) { // 处理课1-4阶段的客户数据 if (classRes.data.class_customers_list) { @@ -437,7 +494,7 @@ async function getTimeline() { } } // 成交阶段 - const payRes = await getPayMoneyCustomers(hasParams ? params : undefined) + const payRes = await withCache('getPayMoneyCustomers', () => getPayMoneyCustomers(hasParams ? params : undefined), hasParams ? params : {}) if(payRes.code === 200) { // 处理成交阶段的客户数据 if (payRes.data.pay_money_customers_list) { @@ -467,7 +524,7 @@ async function getCustomerForm() { customer_name: selectedContact.value.name, } try { - const res = await getCustomerFormInfo(params) + const res = await withCache('getCustomerFormInfo', () => getCustomerFormInfo(params), params) if(res.code === 200) { formInfo.value = res.data } @@ -487,7 +544,7 @@ async function getCustomerChat() { customer_name: selectedContact.value.name, } try { - const res = await getCustomerChatInfo(params) + const res = await withCache('getCustomerChatInfo', () => getCustomerChatInfo(params), params) if(res.code === 200) { chatRecords.value = res.data console.log('聊天数据获取成功:', res.data) @@ -511,7 +568,7 @@ async function getCustomerCall() { customer_name: selectedContact.value.name, } try { - const res = await getCustomerCallInfo(params) + const res = await withCache('getCustomerCallInfo', () => getCustomerCallInfo(params), params) if(res.code === 200) { callRecords.value = res.data console.log('Call Records Data from API:', res.data) @@ -738,9 +795,9 @@ const handleAnalyzeSop = (analyzeData) => { // 销售漏斗 const SalesFunnel = ref([]) async function CenterGetSalesFunnel() { - const params = getRequestParams() - const hasParams = params.user_name - const res = await getSalesFunnel(hasParams?params:undefined) + const params = getRequestParams() + const hasParams = params.user_name + const res = await withCache('getSalesFunnel', () => getSalesFunnel(hasParams ? params : undefined), hasParams ? params : {}) if(res.code === 200){ SalesFunnel.value = res.data /** @@ -763,15 +820,85 @@ const goldContactTime = ref([]) async function CenterGetGoldContactTime() { const params = getRequestParams() const hasParams = params.user_name - const res = await getGoldContactTime(hasParams?params:undefined) + const res = await withCache('getGoldContactTime', () => getGoldContactTime(hasParams ? params : undefined), hasParams ? params : {}) if(res.code === 200){ goldContactTime.value = res.data } } +// 缓存管理功能 +// 清除所有缓存 +function clearCache() { + cache.clear() + console.log('所有缓存已清除') +} + +// 清除特定缓存 +function clearSpecificCache(apiName, params = {}) { + const key = getCacheKey(apiName, params) + cache.delete(key) + console.log(`已清除缓存: ${key}`) +} + +// 获取缓存信息并清理过期缓存 +function getCacheInfo() { + const now = Date.now() + const validCaches = [] + const expiredCaches = [] + + for (const [key, data] of cache.entries()) { + if (isValidCache(data)) { + validCaches.push({ + key, + timestamp: data.timestamp, + age: Math.round((now - data.timestamp) / 1000) + 's' + }) + } else { + expiredCaches.push(key) + cache.delete(key) + } + } + + console.log('有效缓存:', validCaches) + console.log('已清理过期缓存:', expiredCaches) + + return { + validCount: validCaches.length, + expiredCount: expiredCaches.length, + validCaches, + expiredCaches + } +} + +// 强制刷新所有数据(清除缓存并重新调用所有API) +async function forceRefreshAllData() { + console.log('开始强制刷新所有数据...') + clearCache() + + // 重新调用所有API + await Promise.all([ + getCoreKpi(), + getStatisticsData(), + getUrgentProblem(), + getTimeline(), + getCustomerPayMoney(), + CenterGetSalesFunnel(), + CenterGetGoldContactTime(), + // 客户相关数据需要在选中客户后才能获取 + selectedContact.value ? getCustomerForm() : Promise.resolve(), + selectedContact.value ? getCustomerChat() : Promise.resolve(), + selectedContact.value ? getCustomerCall() : Promise.resolve() + ]) + + console.log('所有数据刷新完成') +} + // LIFECYCLE HOOKS onMounted(async () => { try { + // 输出缓存状态信息 + console.log('Sale页面缓存系统已初始化,缓存时长:', CACHE_DURATION / (1000 * 60), '分钟') + isPageLoading.value = true await getCoreKpi() await CenterGetGoldContactTime() @@ -782,6 +909,21 @@ onMounted(async () => { await getCustomerCall() await getTimeline() await getCustomerPayMoney() + + // 输出初始缓存信息 + getCacheInfo() + + // 开发环境下暴露缓存管理函数到全局对象,方便调试 + if (process.env.NODE_ENV === 'development') { + window.saleCache = { + clearCache, + clearSpecificCache, + getCacheInfo, + forceRefreshAllData, + cache + } + console.log('开发模式:缓存管理函数已暴露到 window.saleCache') + } // 等待数据加载完成后选择默认客户 await nextTick(); diff --git a/my-vue-app/src/views/secondTop/secondTop.vue b/my-vue-app/src/views/secondTop/secondTop.vue index 8e7f21c..99cc622 100644 --- a/my-vue-app/src/views/secondTop/secondTop.vue +++ b/my-vue-app/src/views/secondTop/secondTop.vue @@ -159,6 +159,65 @@