feat(api): 添加电话接通率API接口
refactor(cache): 将缓存系统重构为独立模块并添加测试页面 fix: 修复客户详情中电话接通率显示格式问题 refactor: 移除各页面中的缓存逻辑,统一使用缓存store feat: 在客户详情中添加通话分析API调用 fix: 修正导出客户API的URL路径 chore: 更新开发环境配置注释
This commit is contained in:
@@ -77,5 +77,7 @@ export const getGoldContactTime = (params) => {
|
|||||||
export const getAvgCallTime = (params) => {
|
export const getAvgCallTime = (params) => {
|
||||||
return https.post('/api/v1/sales/get_avg_call_time', params)
|
return https.post('/api/v1/sales/get_avg_call_time', params)
|
||||||
}
|
}
|
||||||
|
// 电话接通率 /api/v1/sales/get_call_success_rate
|
||||||
|
export const getCallSuccessRate = (params) => {
|
||||||
|
return https.post('/api/v1/sales/get_call_success_rate', params)
|
||||||
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export const cancelSwitchHistoryCampPeriod = (params) => {
|
|||||||
|
|
||||||
// 一键导出 api/v1/level_four/overview/export_customers
|
// 一键导出 api/v1/level_four/overview/export_customers
|
||||||
export const exportCustomers = (params) => {
|
export const exportCustomers = (params) => {
|
||||||
return https.post('http://192.168.15.56:8890/api/v1/level_four/overview/export_customers', params)
|
return https.post('/api/v1/level_four/overview/export_customers', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
135
my-vue-app/src/stores/cache.js
Normal file
135
my-vue-app/src/stores/cache.js
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export const useCacheStore = defineStore('cache', () => {
|
||||||
|
// 缓存Map
|
||||||
|
const cache = ref(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.value.set(key, {
|
||||||
|
data,
|
||||||
|
timestamp: Date.now()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取缓存
|
||||||
|
const getCache = (key) => {
|
||||||
|
const cacheData = cache.value.get(key)
|
||||||
|
if (isValidCache(cacheData)) {
|
||||||
|
return cacheData.data
|
||||||
|
}
|
||||||
|
// 如果缓存过期,删除它
|
||||||
|
if (cacheData) {
|
||||||
|
cache.value.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 clearCache = () => {
|
||||||
|
cache.value.clear()
|
||||||
|
console.log('所有缓存已清除')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除特定缓存
|
||||||
|
const clearSpecificCache = (apiName, params = {}) => {
|
||||||
|
const key = getCacheKey(apiName, params)
|
||||||
|
cache.value.delete(key)
|
||||||
|
console.log(`已清除缓存: ${key}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取缓存信息并清理过期缓存
|
||||||
|
const getCacheInfo = () => {
|
||||||
|
const now = Date.now()
|
||||||
|
const validCaches = []
|
||||||
|
const expiredCaches = []
|
||||||
|
|
||||||
|
for (const [key, data] of cache.value.entries()) {
|
||||||
|
if (isValidCache(data)) {
|
||||||
|
validCaches.push({
|
||||||
|
key,
|
||||||
|
timestamp: data.timestamp,
|
||||||
|
age: Math.round((now - data.timestamp) / 1000) + 's'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
expiredCaches.push(key)
|
||||||
|
cache.value.delete(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
validCount: validCaches.length,
|
||||||
|
expiredCount: expiredCaches.length,
|
||||||
|
validCaches,
|
||||||
|
expiredCaches
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除过期缓存
|
||||||
|
const clearExpiredCache = () => {
|
||||||
|
const info = getCacheInfo()
|
||||||
|
console.log(`清理了 ${info.expiredCount} 个过期缓存`)
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取缓存统计信息
|
||||||
|
const getCacheStats = () => {
|
||||||
|
return {
|
||||||
|
totalCount: cache.value.size,
|
||||||
|
duration: CACHE_DURATION / (1000 * 60) + '分钟',
|
||||||
|
...getCacheInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// 状态
|
||||||
|
cache,
|
||||||
|
CACHE_DURATION,
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
getCacheKey,
|
||||||
|
isValidCache,
|
||||||
|
setCache,
|
||||||
|
getCache,
|
||||||
|
withCache,
|
||||||
|
clearCache,
|
||||||
|
clearSpecificCache,
|
||||||
|
getCacheInfo,
|
||||||
|
clearExpiredCache,
|
||||||
|
getCacheStats
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -6,7 +6,7 @@ import { useUserStore } from '@/stores/user'
|
|||||||
// 创建axios实例
|
// 创建axios实例
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: 'https://mldash.nycjy.cn/' || '', // API基础路径,支持完整URL
|
baseURL: 'https://mldash.nycjy.cn/' || '', // API基础路径,支持完整URL
|
||||||
// baseURL: 'http://192.168.15.121:8889' || '', // API基础路径,支持完整URL
|
// baseURL: 'http://192.168.15.121:8890' || '', // API基础路径,支持完整URL
|
||||||
timeout: 100000, // 请求超时时间
|
timeout: 100000, // 请求超时时间
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=UTF-8'
|
'Content-Type': 'application/json;charset=UTF-8'
|
||||||
|
|||||||
@@ -83,51 +83,6 @@ import { useRouter } from "vue-router";
|
|||||||
import {getGroupAbnormalResponse, getWeekTotalCall, getWeekAddCustomerTotal, getWeekAddDealTotal,
|
import {getGroupAbnormalResponse, getWeekTotalCall, getWeekAddCustomerTotal, getWeekAddDealTotal,
|
||||||
getWeekAddFeeTotal, getGroupFunnel,getPayDepositToMoneyRate,getGroupRanking, getGroupCallDuration} from "@/api/manager.js";
|
getWeekAddFeeTotal, getGroupFunnel,getPayDepositToMoneyRate,getGroupRanking, getGroupCallDuration} 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 = [
|
const teamMembers = [
|
||||||
{
|
{
|
||||||
@@ -198,7 +153,7 @@ async function TeamGetGroupAbnormalResponse() {
|
|||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
try {
|
try {
|
||||||
const response = await withCache('getGroupAbnormalResponse', () => getGroupAbnormalResponse(hasParams ? params : undefined), hasParams ? params : {})
|
const response = await getGroupAbnormalResponse(hasParams ? params : undefined)
|
||||||
const rawData = response.data
|
const rawData = response.data
|
||||||
|
|
||||||
// 转换数据格式,生成预警消息
|
// 转换数据格式,生成预警消息
|
||||||
@@ -243,7 +198,7 @@ async function TeamGetGroupAbnormalResponse() {
|
|||||||
async function TeamGetWeekTotalCall() {
|
async function TeamGetWeekTotalCall() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getWeekTotalCall', () => getWeekTotalCall(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getWeekTotalCall(hasParams ? params : undefined)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
weekTotalData.value.week_total_call = res.data
|
weekTotalData.value.week_total_call = res.data
|
||||||
@@ -253,7 +208,7 @@ async function TeamGetWeekTotalCall() {
|
|||||||
async function TeamGetGroupCallDuration() {
|
async function TeamGetGroupCallDuration() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getGroupCallDuration', () => getGroupCallDuration(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getGroupCallDuration(hasParams ? params : undefined)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
weekTotalData.value.group_call_duration = res.data
|
weekTotalData.value.group_call_duration = res.data
|
||||||
@@ -263,7 +218,7 @@ async function TeamGetGroupCallDuration() {
|
|||||||
async function TeamGetWeekAddCustomerTotal() {
|
async function TeamGetWeekAddCustomerTotal() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getWeekAddCustomerTotal', () => getWeekAddCustomerTotal(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getWeekAddCustomerTotal(hasParams ? params : undefined)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
weekTotalData.value.week_add_customer_total = res.data
|
weekTotalData.value.week_add_customer_total = res.data
|
||||||
@@ -273,7 +228,7 @@ async function TeamGetWeekAddCustomerTotal() {
|
|||||||
async function TeamGetWeekAddDealTotal() {
|
async function TeamGetWeekAddDealTotal() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getWeekAddDealTotal', () => getWeekAddDealTotal(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getWeekAddDealTotal(hasParams ? params : undefined)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
weekTotalData.value.week_add_deal_total = res.data
|
weekTotalData.value.week_add_deal_total = res.data
|
||||||
@@ -286,7 +241,7 @@ async function TeamGetWeekAddDealTotal() {
|
|||||||
async function TeamGetWeekAddFeeTotal() {
|
async function TeamGetWeekAddFeeTotal() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getPayDepositToMoneyRate', () => getPayDepositToMoneyRate(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getPayDepositToMoneyRate(hasParams ? params : undefined)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
weekTotalData.value.pay_deposit_to_money_rate = res.data
|
weekTotalData.value.pay_deposit_to_money_rate = res.data
|
||||||
@@ -296,7 +251,7 @@ async function TeamGetWeekAddFeeTotal() {
|
|||||||
async function TeamGetGroupFunnel() {
|
async function TeamGetGroupFunnel() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getGroupFunnel', () => getGroupFunnel(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getGroupFunnel(hasParams ? params : undefined)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
weekTotalData.value.group_funnel = res.data
|
weekTotalData.value.group_funnel = res.data
|
||||||
@@ -321,7 +276,7 @@ const groupRanking = ref({})
|
|||||||
async function TeamGetGroupRanking() {
|
async function TeamGetGroupRanking() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getGroupRanking', () => getGroupRanking(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getGroupRanking(hasParams ? params : undefined)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
groupRanking.value = res.data
|
groupRanking.value = res.data
|
||||||
@@ -339,76 +294,11 @@ const selectMember = (member) => {
|
|||||||
selectedMember.value = 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(),
|
|
||||||
TeamGetGroupCallDuration(),
|
|
||||||
TeamGetWeekAddCustomerTotal(),
|
|
||||||
TeamGetWeekAddDealTotal(),
|
|
||||||
TeamGetWeekAddFeeTotal(),
|
|
||||||
TeamGetGroupFunnel(),
|
|
||||||
TeamGetGroupRanking()
|
|
||||||
])
|
|
||||||
|
|
||||||
console.log('所有数据刷新完成')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 团队异常预警
|
// 团队异常预警
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 输出缓存状态信息
|
|
||||||
console.log('Manager页面缓存系统已初始化,缓存时长:', CACHE_DURATION / (1000 * 60), '分钟')
|
|
||||||
|
|
||||||
await TeamGetGroupAbnormalResponse()
|
await TeamGetGroupAbnormalResponse()
|
||||||
await TeamGetWeekTotalCall()
|
await TeamGetWeekTotalCall()
|
||||||
await TeamGetGroupCallDuration()
|
await TeamGetGroupCallDuration()
|
||||||
@@ -417,21 +307,6 @@ onMounted(async () => {
|
|||||||
await TeamGetWeekAddFeeTotal()
|
await TeamGetWeekAddFeeTotal()
|
||||||
await TeamGetGroupFunnel()
|
await TeamGetGroupFunnel()
|
||||||
await TeamGetGroupRanking()
|
await TeamGetGroupRanking()
|
||||||
|
|
||||||
// 输出初始缓存信息
|
|
||||||
getCacheInfo()
|
|
||||||
|
|
||||||
// 开发环境下暴露缓存管理函数到全局对象,方便调试
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
window.managerCache = {
|
|
||||||
clearCache,
|
|
||||||
clearSpecificCache,
|
|
||||||
getCacheInfo,
|
|
||||||
forceRefreshAllData,
|
|
||||||
cache
|
|
||||||
}
|
|
||||||
console.log('开发模式:缓存管理函数已暴露到 window.managerCache')
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -94,6 +94,7 @@
|
|||||||
import { ref, watch, computed } from 'vue';
|
import { ref, watch, computed } from 'vue';
|
||||||
import { SimpleChatService } from '@/utils/ChatService.js';
|
import { SimpleChatService } from '@/utils/ChatService.js';
|
||||||
import MarkdownIt from 'markdown-it';
|
import MarkdownIt from 'markdown-it';
|
||||||
|
import https from '@/utils/https'
|
||||||
|
|
||||||
// 定义props
|
// 定义props
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -115,6 +116,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(999999999,props.selectedContact);
|
||||||
// 分析结果状态
|
// 分析结果状态
|
||||||
const basicAnalysisResult = ref(''); // 基础信息分析结果
|
const basicAnalysisResult = ref(''); // 基础信息分析结果
|
||||||
const sopAnalysisResult = ref(''); // SOP通话分析结果
|
const sopAnalysisResult = ref(''); // SOP通话分析结果
|
||||||
@@ -349,16 +351,20 @@ ${callData.length > 0 && callData[0].record_context ? callData[0].record_context
|
|||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await chatService.sendMessage(
|
// await chatService.sendMessage(
|
||||||
query,
|
// query,
|
||||||
(update) => {
|
// (update) => {
|
||||||
sopAnalysisResult.value = update.content;
|
// sopAnalysisResult.value = update.content;
|
||||||
},
|
// },
|
||||||
() => {
|
// () => {
|
||||||
isSopAnalysisLoading.value = false;
|
// isSopAnalysisLoading.value = false;
|
||||||
console.log('SOP通话分析完成');
|
// console.log('SOP通话分析完成');
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
|
const res= await https.get('http://192.168.3.112:6002/api/v1/call',{
|
||||||
|
wechat_id:props.selectedContact.wechat_id
|
||||||
|
})
|
||||||
|
sopAnalysisResult.value = res.data.report_content;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('SOP通话分析失败:', error);
|
console.error('SOP通话分析失败:', error);
|
||||||
sopAnalysisResult.value = `分析失败: ${error.message}`;
|
sopAnalysisResult.value = `分析失败: ${error.message}`;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<p>今日通话 <i class="info-icon" @mouseenter="showTooltip('totalCalls', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
<p>今日通话 <i class="info-icon" @mouseenter="showTooltip('totalCalls', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="kpi-item">
|
<div class="kpi-item">
|
||||||
<div class="kpi-value">{{ props.kpiData.successRate }}%</div>
|
<div class="kpi-value">{{ props.kpiData.successRate }}</div>
|
||||||
<p>电话接通率 <i class="info-icon" @mouseenter="showTooltip('successRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
<p>电话接通率 <i class="info-icon" @mouseenter="showTooltip('successRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="kpi-item">
|
<div class="kpi-item">
|
||||||
|
|||||||
@@ -142,64 +142,8 @@ import UserDropdown from "@/components/UserDropdown.vue";
|
|||||||
import Loading from "@/components/Loading.vue";
|
import Loading from "@/components/Loading.vue";
|
||||||
import {getCustomerAttendance,getTodayCall,getProblemDistribution,getTableFillingRate,getAverageResponseTime,
|
import {getCustomerAttendance,getTodayCall,getProblemDistribution,getTableFillingRate,getAverageResponseTime,
|
||||||
getWeeklyActiveCommunicationRate,getTimeoutResponseRate,getCustomerCallInfo,getCustomerChatInfo,getCustomerFormInfo,
|
getWeeklyActiveCommunicationRate,getTimeoutResponseRate,getCustomerCallInfo,getCustomerChatInfo,getCustomerFormInfo,
|
||||||
getConversionRateAndAllocatedData,getCustomerAttendanceAfterClass4,getPayMoneyCustomers,getSalesFunnel,getGoldContactTime,getAvgCallTime} from "@/api/api.js"
|
getConversionRateAndAllocatedData,getCustomerAttendanceAfterClass4,getPayMoneyCustomers,getSalesFunnel,getGoldContactTime,
|
||||||
|
getAvgCallTime,getCallSuccessRate} 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();
|
const router = useRouter();
|
||||||
@@ -220,7 +164,6 @@ const getRequestParams = () => {
|
|||||||
if (routeUserName) {
|
if (routeUserName) {
|
||||||
params.user_name = routeUserName
|
params.user_name = routeUserName
|
||||||
}
|
}
|
||||||
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,6 +272,8 @@ const formInfo = ref({});
|
|||||||
const callRecords = ref([]);
|
const callRecords = ref([]);
|
||||||
// 聊天记录
|
// 聊天记录
|
||||||
const chatRecords = ref([]);
|
const chatRecords = ref([]);
|
||||||
|
// 电话接通率
|
||||||
|
const callSuccessRate = ref(0)
|
||||||
|
|
||||||
// MOCK DATA (Should ideally come from a store or API)
|
// MOCK DATA (Should ideally come from a store or API)
|
||||||
const MOCK_DATA = reactive({
|
const MOCK_DATA = reactive({
|
||||||
@@ -366,24 +311,27 @@ async function getCoreKpi() {
|
|||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
|
|
||||||
// 今日通话数据
|
// 今日通话数据
|
||||||
const res = await withCache('getTodayCall', () => getTodayCall(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getTodayCall(hasParams ? params : undefined)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
kpiDataState.totalCalls = res.data.today_call
|
kpiDataState.totalCalls = res.data.today_call
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转化率、分配数据量、加微率
|
// 转化率、分配数据量、加微率
|
||||||
const conversionRes = await withCache('getConversionRateAndAllocatedData', () => getConversionRateAndAllocatedData(hasParams ? params : undefined), hasParams ? params : {})
|
const conversionRes = await getConversionRateAndAllocatedData(hasParams ? params : undefined)
|
||||||
if (conversionRes.code === 200) {
|
if (conversionRes.code === 200) {
|
||||||
kpiDataState.conversionRate = conversionRes.data.conversion_rate || 0
|
kpiDataState.conversionRate = conversionRes.data.conversion_rate || 0
|
||||||
kpiDataState.assignedData = conversionRes.data.all_count || 0
|
kpiDataState.assignedData = conversionRes.data.all_count || 0
|
||||||
kpiDataState.wechatAddRate = conversionRes.data.plus_v_conversion_rate || 0
|
kpiDataState.wechatAddRate = conversionRes.data.plus_v_conversion_rate || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 平均通话时长
|
// 平均通话时长
|
||||||
const avgCallTimeRes = await withCache('getAvgCallTime', () => getAvgCallTime(hasParams ? params : undefined), hasParams ? params : {})
|
const avgCallTimeRes = await getAvgCallTime(hasParams ? params : undefined)
|
||||||
if (avgCallTimeRes.code === 200) {
|
if (avgCallTimeRes.code === 200) {
|
||||||
kpiDataState.avgDuration = avgCallTimeRes.data.call_time || 0
|
kpiDataState.avgDuration = avgCallTimeRes.data.call_time || 0
|
||||||
}
|
}
|
||||||
|
// 电话接通率
|
||||||
|
const callSuccessRateRes = await getCallSuccessRate(hasParams ? params : undefined)
|
||||||
|
if (callSuccessRateRes.code === 200) {
|
||||||
|
kpiDataState.successRate = callSuccessRateRes.data.call_success_rate || 0
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取核心KPI数据失败:', error)
|
console.error('获取核心KPI数据失败:', error)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -398,25 +346,25 @@ async function getStatisticsData() {
|
|||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
|
|
||||||
// 获取表单填写率
|
// 获取表单填写率
|
||||||
const fillingRateRes = await withCache('getTableFillingRate', () => getTableFillingRate(hasParams ? params : undefined), hasParams ? params : {})
|
const fillingRateRes = await getTableFillingRate(hasParams ? params : undefined)
|
||||||
if (fillingRateRes.code === 200) {
|
if (fillingRateRes.code === 200) {
|
||||||
statisticsData.formCompletionRate = fillingRateRes.data.filling_rate
|
statisticsData.formCompletionRate = fillingRateRes.data.filling_rate
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取平均响应时间
|
// 获取平均响应时间
|
||||||
const avgResponseRes = await withCache('getAverageResponseTime', () => getAverageResponseTime(hasParams ? params : undefined), hasParams ? params : {})
|
const avgResponseRes = await getAverageResponseTime(hasParams ? params : undefined)
|
||||||
if (avgResponseRes.code === 200) {
|
if (avgResponseRes.code === 200) {
|
||||||
statisticsData.averageResponseTime = avgResponseRes.data.average_minutes
|
statisticsData.averageResponseTime = avgResponseRes.data.average_minutes
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取客户沟通率
|
// 获取客户沟通率
|
||||||
const communicationRes = await withCache('getWeeklyActiveCommunicationRate', () => getWeeklyActiveCommunicationRate(hasParams ? params : undefined), hasParams ? params : {})
|
const communicationRes = await getWeeklyActiveCommunicationRate(hasParams ? params : undefined)
|
||||||
if (communicationRes.code === 200) {
|
if (communicationRes.code === 200) {
|
||||||
statisticsData.customerCommunicationRate = communicationRes.data.communication_rate
|
statisticsData.customerCommunicationRate = communicationRes.data.communication_rate
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取超时响应率
|
// 获取超时响应率
|
||||||
const timeoutRes = await withCache('getTimeoutResponseRate', () => getTimeoutResponseRate(hasParams ? params : undefined), hasParams ? params : {})
|
const timeoutRes = await getTimeoutResponseRate(hasParams ? params : undefined)
|
||||||
if (timeoutRes.code === 200) {
|
if (timeoutRes.code === 200) {
|
||||||
statisticsData.timeoutResponseRate = timeoutRes.data.overtime_rate_600
|
statisticsData.timeoutResponseRate = timeoutRes.data.overtime_rate_600
|
||||||
statisticsData.severeTimeoutRate = timeoutRes.data.overtime_rate_800
|
statisticsData.severeTimeoutRate = timeoutRes.data.overtime_rate_800
|
||||||
@@ -434,7 +382,7 @@ async function getUrgentProblem() {
|
|||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
|
|
||||||
const res = await withCache('getProblemDistribution', () => getProblemDistribution(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getProblemDistribution(hasParams ? params : undefined)
|
||||||
if(res.code === 200) {
|
if(res.code === 200) {
|
||||||
// 将API返回的对象格式转换为数组格式
|
// 将API返回的对象格式转换为数组格式
|
||||||
const problemDistributionCount = res.data.problem_distribution_count
|
const problemDistributionCount = res.data.problem_distribution_count
|
||||||
@@ -453,7 +401,7 @@ async function getTimeline() {
|
|||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
// 前6个阶段
|
// 前6个阶段
|
||||||
const res = await withCache('getCustomerAttendance', () => getCustomerAttendance(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getCustomerAttendance(hasParams ? params : undefined)
|
||||||
if(res.code === 200) {
|
if(res.code === 200) {
|
||||||
// 处理时间线数据
|
// 处理时间线数据
|
||||||
if (res.data.timeline) {
|
if (res.data.timeline) {
|
||||||
@@ -471,7 +419,7 @@ async function getTimeline() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 后4个阶段
|
// 后4个阶段
|
||||||
const classRes = await withCache('getCustomerAttendanceAfterClass4', () => getCustomerAttendanceAfterClass4(hasParams ? params : undefined), hasParams ? params : {})
|
const classRes = await getCustomerAttendanceAfterClass4(hasParams ? params : undefined)
|
||||||
if(classRes.code === 200) {
|
if(classRes.code === 200) {
|
||||||
// 处理课1-4阶段的客户数据
|
// 处理课1-4阶段的客户数据
|
||||||
if (classRes.data.class_customers_list) {
|
if (classRes.data.class_customers_list) {
|
||||||
@@ -547,7 +495,7 @@ async function getTimeline() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 成交阶段
|
// 成交阶段
|
||||||
const payRes = await withCache('getPayMoneyCustomers', () => getPayMoneyCustomers(hasParams ? params : undefined), hasParams ? params : {})
|
const payRes = await getPayMoneyCustomers(hasParams ? params : undefined)
|
||||||
if(payRes.code === 200) {
|
if(payRes.code === 200) {
|
||||||
// 处理成交阶段的客户数据
|
// 处理成交阶段的客户数据
|
||||||
if (payRes.data.pay_money_customers_list) {
|
if (payRes.data.pay_money_customers_list) {
|
||||||
@@ -577,7 +525,7 @@ async function getCustomerForm() {
|
|||||||
customer_name: selectedContact.value.name,
|
customer_name: selectedContact.value.name,
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await withCache('getCustomerFormInfo', () => getCustomerFormInfo(params), params)
|
const res = await getCustomerFormInfo(params)
|
||||||
if(res.code === 200) {
|
if(res.code === 200) {
|
||||||
formInfo.value = res.data
|
formInfo.value = res.data
|
||||||
}
|
}
|
||||||
@@ -596,7 +544,7 @@ async function getCustomerChat() {
|
|||||||
customer_name: selectedContact.value.name,
|
customer_name: selectedContact.value.name,
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await withCache('getCustomerChatInfo', () => getCustomerChatInfo(params), params)
|
const res = await getCustomerChatInfo(params)
|
||||||
if(res.code === 200) {
|
if(res.code === 200) {
|
||||||
chatRecords.value = res.data
|
chatRecords.value = res.data
|
||||||
} else {
|
} else {
|
||||||
@@ -617,7 +565,7 @@ async function getCustomerCall() {
|
|||||||
customer_name: selectedContact.value.name,
|
customer_name: selectedContact.value.name,
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await withCache('getCustomerCallInfo', () => getCustomerCallInfo(params), params)
|
const res = await getCustomerCallInfo(params)
|
||||||
if(res.code === 200) {
|
if(res.code === 200) {
|
||||||
callRecords.value = res.data
|
callRecords.value = res.data
|
||||||
console.log('Call Records Data from API:', res.data)
|
console.log('Call Records Data from API:', res.data)
|
||||||
@@ -631,6 +579,7 @@ async function getCustomerCall() {
|
|||||||
const kpiData = computed(() => kpiDataState);
|
const kpiData = computed(() => kpiDataState);
|
||||||
// COMPUTED PROPERTIES
|
// COMPUTED PROPERTIES
|
||||||
const selectedContact = computed(() => {
|
const selectedContact = computed(() => {
|
||||||
|
console.log(999999999,formattedCustomersList.value);
|
||||||
// 优先从API数据中查找
|
// 优先从API数据中查找
|
||||||
if (formattedCustomersList.value.length > 0) {
|
if (formattedCustomersList.value.length > 0) {
|
||||||
return formattedCustomersList.value.find((c) => c.id === selectedContactId.value) || null;
|
return formattedCustomersList.value.find((c) => c.id === selectedContactId.value) || null;
|
||||||
@@ -672,6 +621,7 @@ const formattedCustomersList = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return customersList.value?.map(customer => ({
|
return customersList.value?.map(customer => ({
|
||||||
|
wechat_id: customer.customer_wechat_id,
|
||||||
id: customer.customer_name, // 使用客户姓名作为唯一标识
|
id: customer.customer_name, // 使用客户姓名作为唯一标识
|
||||||
name: customer.customer_name,
|
name: customer.customer_name,
|
||||||
phone: customer.phone,
|
phone: customer.phone,
|
||||||
@@ -871,7 +821,7 @@ const SalesFunnel = ref([])
|
|||||||
async function CenterGetSalesFunnel() {
|
async function CenterGetSalesFunnel() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getSalesFunnel', () => getSalesFunnel(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getSalesFunnel(hasParams ? params : undefined)
|
||||||
if(res.code === 200){
|
if(res.code === 200){
|
||||||
SalesFunnel.value = res.data
|
SalesFunnel.value = res.data
|
||||||
/**
|
/**
|
||||||
@@ -894,56 +844,15 @@ const goldContactTime = ref([])
|
|||||||
async function CenterGetGoldContactTime() {
|
async function CenterGetGoldContactTime() {
|
||||||
const params = getRequestParams()
|
const params = getRequestParams()
|
||||||
const hasParams = params.user_name
|
const hasParams = params.user_name
|
||||||
const res = await withCache('getGoldContactTime', () => getGoldContactTime(hasParams ? params : undefined), hasParams ? params : {})
|
const res = await getGoldContactTime(hasParams ? params : undefined)
|
||||||
if(res.code === 200){
|
if(res.code === 200){
|
||||||
goldContactTime.value = res.data
|
goldContactTime.value = res.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存管理功能
|
// 强制刷新所有数据(重新调用所有API)
|
||||||
// 清除所有缓存
|
|
||||||
function clearCache() {
|
|
||||||
cache.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清除特定缓存
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
validCount: validCaches.length,
|
|
||||||
expiredCount: expiredCaches.length,
|
|
||||||
validCaches,
|
|
||||||
expiredCaches
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 强制刷新所有数据(清除缓存并重新调用所有API)
|
|
||||||
async function forceRefreshAllData() {
|
async function forceRefreshAllData() {
|
||||||
console.log('开始强制刷新所有数据...')
|
console.log('开始强制刷新所有数据...')
|
||||||
clearCache()
|
|
||||||
|
|
||||||
// 重新调用所有API
|
// 重新调用所有API
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@@ -951,7 +860,6 @@ async function forceRefreshAllData() {
|
|||||||
getStatisticsData(),
|
getStatisticsData(),
|
||||||
getUrgentProblem(),
|
getUrgentProblem(),
|
||||||
getTimeline(),
|
getTimeline(),
|
||||||
getCustomerPayMoney(),
|
|
||||||
CenterGetSalesFunnel(),
|
CenterGetSalesFunnel(),
|
||||||
CenterGetGoldContactTime(),
|
CenterGetGoldContactTime(),
|
||||||
// 客户相关数据需要在选中客户后才能获取
|
// 客户相关数据需要在选中客户后才能获取
|
||||||
@@ -975,19 +883,11 @@ onMounted(async () => {
|
|||||||
await getUrgentProblem()
|
await getUrgentProblem()
|
||||||
await getCustomerCall()
|
await getCustomerCall()
|
||||||
await getTimeline()
|
await getTimeline()
|
||||||
await getCustomerPayMoney()
|
|
||||||
|
|
||||||
// 输出初始缓存信息
|
// 开发环境下暴露数据刷新函数到全局对象,方便调试
|
||||||
getCacheInfo()
|
|
||||||
|
|
||||||
// 开发环境下暴露缓存管理函数到全局对象,方便调试
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
window.saleCache = {
|
window.saleData = {
|
||||||
clearCache,
|
forceRefreshAllData
|
||||||
clearSpecificCache,
|
|
||||||
getCacheInfo,
|
|
||||||
forceRefreshAllData,
|
|
||||||
cache
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
173
my-vue-app/src/views/test/CacheTest.vue
Normal file
173
my-vue-app/src/views/test/CacheTest.vue
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<template>
|
||||||
|
<div class="cache-test">
|
||||||
|
<h1>缓存系统测试页面</h1>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>缓存统计信息</h2>
|
||||||
|
<div class="cache-stats">
|
||||||
|
<p>总缓存数量: {{ cacheStats.totalCount }}</p>
|
||||||
|
<p>有效缓存数量: {{ cacheStats.validCount }}</p>
|
||||||
|
<p>过期缓存数量: {{ cacheStats.expiredCount }}</p>
|
||||||
|
<p>缓存时长: {{ cacheStats.duration }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>缓存操作</h2>
|
||||||
|
<div class="cache-actions">
|
||||||
|
<button @click="refreshStats" class="btn primary">刷新统计</button>
|
||||||
|
<button @click="clearAllCache" class="btn secondary">清除所有缓存</button>
|
||||||
|
<button @click="clearExpiredCache" class="btn secondary">清除过期缓存</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>缓存详情</h2>
|
||||||
|
<div class="cache-details">
|
||||||
|
<div v-if="cacheStats.validCaches && cacheStats.validCaches.length > 0">
|
||||||
|
<h3>有效缓存列表:</h3>
|
||||||
|
<ul>
|
||||||
|
<li v-for="cache in cacheStats.validCaches" :key="cache.key">
|
||||||
|
<strong>{{ cache.key }}</strong> - 存活时间: {{ cache.age }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<p>暂无有效缓存</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { useCacheStore } from '@/stores/cache'
|
||||||
|
|
||||||
|
// 缓存store
|
||||||
|
const cacheStore = useCacheStore()
|
||||||
|
|
||||||
|
// 缓存统计信息
|
||||||
|
const cacheStats = ref({
|
||||||
|
totalCount: 0,
|
||||||
|
validCount: 0,
|
||||||
|
expiredCount: 0,
|
||||||
|
duration: '30分钟',
|
||||||
|
validCaches: []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 刷新统计信息
|
||||||
|
const refreshStats = () => {
|
||||||
|
const stats = cacheStore.getCacheStats()
|
||||||
|
cacheStats.value = stats
|
||||||
|
console.log('缓存统计信息:', stats)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除所有缓存
|
||||||
|
const clearAllCache = () => {
|
||||||
|
cacheStore.clearCache()
|
||||||
|
refreshStats()
|
||||||
|
console.log('已清除所有缓存')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除过期缓存
|
||||||
|
const clearExpiredCache = () => {
|
||||||
|
const info = cacheStore.clearExpiredCache()
|
||||||
|
refreshStats()
|
||||||
|
console.log('清除过期缓存结果:', info)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载时获取统计信息
|
||||||
|
onMounted(() => {
|
||||||
|
refreshStats()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.cache-test {
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cache-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 4px solid #3b82f6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cache-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&.primary {
|
||||||
|
background: #3b82f6;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #2563eb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.secondary {
|
||||||
|
background: #6b7280;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #4b5563;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cache-details {
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 3px solid #10b981;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3 {
|
||||||
|
color: #1f2937;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user