配置客户管理的缓存

This commit is contained in:
WindowBird 2025-11-07 18:01:19 +08:00
parent 22823e520f
commit 20a88c45b8
3 changed files with 213 additions and 43 deletions

View File

@ -38,6 +38,9 @@
class="customer-list" class="customer-list"
:class="{ 'with-filter': showFilter }" :class="{ 'with-filter': showFilter }"
scroll-y scroll-y
refresher-enabled
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
> >
<view style="padding-inline: 8px"> <view style="padding-inline: 8px">
<view <view
@ -123,21 +126,24 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted, watch } from 'vue'; import { ref, computed, onMounted, watch, onActivated } from 'vue';
import FabPlus from '@/components/FabPlus.vue'; import FabPlus from '@/components/FabPlus.vue';
import { getCustomerList } from '@/common/api'; import { useCustomerStore } from '@/store/customer';
// 使 store
const customerStore = useCustomerStore();
// //
const showFilter = ref(false); const showFilter = ref(false);
const filterStatus = ref(''); const filterStatus = ref('');
// // store
const loading = ref(false);
//
const customers = ref([]); const customers = ref([]);
// //
const refreshing = ref(false);
// 使
const filteredCustomers = computed(() => { const filteredCustomers = computed(() => {
if (!filterStatus.value) { if (!filterStatus.value) {
return customers.value; return customers.value;
@ -154,6 +160,9 @@ const filteredCustomers = computed(() => {
return customers.value.filter(customer => customer.status === targetStatus); return customers.value.filter(customer => customer.status === targetStatus);
}); });
// store
const loading = computed(() => customerStore.loading);
// //
const getStatusClass = (status) => { const getStatusClass = (status) => {
return { return {
@ -199,42 +208,18 @@ const formatDateTime = (dateTime) => {
} }
}; };
// // 使 store
const loadCustomerList = async () => { const loadCustomerList = async (forceRefresh = false) => {
loading.value = true;
try { try {
// // 使 store
const params = {}; //
const data = await customerStore.fetchCustomerList({}, forceRefresh);
// statusList //
if (filterStatus.value) { customers.value = data || [];
const statusMap = {
'following': ['1'], //
'pending': ['2'] //
};
if (statusMap[filterStatus.value]) {
params.statusList = statusMap[filterStatus.value];
}
}
// API
const res = await getCustomerList(params);
// API: { total: number, rows: array }
if (res && res.rows && Array.isArray(res.rows)) {
customers.value = res.rows;
} else if (res && Array.isArray(res)) {
//
customers.value = res;
} else {
customers.value = [];
}
} catch (error) { } catch (error) {
console.error('加载客户列表失败:', error); console.error('加载客户列表失败:', error);
uni.$uv.toast('加载客户列表失败'); uni.$uv.toast('加载客户列表失败');
customers.value = []; customers.value = [];
} finally {
loading.value = false;
} }
}; };
@ -305,14 +290,42 @@ const handleAddCustomer = () => {
}); });
}; };
// //
//
watch(filterStatus, () => { watch(filterStatus, () => {
loadCustomerList(); // filteredCustomers computed
console.log('筛选状态变化:', filterStatus.value);
}); });
// //
onMounted(() => { onMounted(() => {
loadCustomerList(); loadCustomerList(false); // 使
});
//
const onRefresh = async () => {
refreshing.value = true;
try {
//
await loadCustomerList(true);
uni.$uv.toast('刷新成功');
} catch (error) {
console.error('刷新失败:', error);
uni.$uv.toast('刷新失败');
} finally {
//
setTimeout(() => {
refreshing.value = false;
}, 500);
}
};
// 使 v-show
onActivated(() => {
//
if (!customerStore.isCacheValid) {
loadCustomerList(false);
}
}); });
</script> </script>

View File

@ -6,8 +6,8 @@
<!-- 内容区域 --> <!-- 内容区域 -->
<view class="content-wrapper"> <view class="content-wrapper">
<!-- 客户管理底部导航栏选中时显示 --> <!-- 客户管理底部导航栏选中时显示使用 v-show 避免组件销毁重建 -->
<CustomerManagement v-if="value === 3" /> <CustomerManagement v-show="value === 3" />
<!-- 其他内容底部导航栏未选中客户管理时显示 --> <!-- 其他内容底部导航栏未选中客户管理时显示 -->
<template v-else> <template v-else>
@ -193,6 +193,11 @@ onShow(() => {
:deep(.customer-management) { :deep(.customer-management) {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
/* 使用 v-show 隐藏时确保不可见 */
&[style*="display: none"] {
display: none !important;
}
} }
} }

152
store/customer.js Normal file
View File

@ -0,0 +1,152 @@
import { defineStore } from 'pinia'
import { getCustomerList } from '@/common/api/customer'
/**
* 客户管理 Store
* 用于管理客户列表数据缓存避免重复请求
*/
export const useCustomerStore = defineStore('customer', {
state: () => {
return {
// 全部客户列表缓存(不包含筛选条件)
allCustomers: [],
// 缓存时间戳
cacheTimestamp: null,
// 缓存有效期毫秒默认5分钟
cacheExpireTime: 5 * 60 * 1000,
// 加载状态
loading: false,
// 最后请求的参数(用于判断是否需要刷新)
lastParams: null
}
},
getters: {
/**
* 判断缓存是否有效
*/
isCacheValid: (state) => {
if (!state.cacheTimestamp || state.allCustomers.length === 0) {
return false
}
const now = Date.now()
return (now - state.cacheTimestamp) < state.cacheExpireTime
},
/**
* 根据状态筛选客户列表
* @param {string} status - 筛选状态'1' 正在跟进, '2' 待跟进, '' 全部
*/
getFilteredCustomers: (state) => {
return (status = '') => {
if (!status) {
return state.allCustomers
}
return state.allCustomers.filter(customer => customer.status === status)
}
}
},
actions: {
/**
* 获取客户列表带缓存机制
* @param {Object} params - 请求参数
* @param {boolean} forceRefresh - 是否强制刷新忽略缓存
* @returns {Promise<Array>} 返回客户列表
*/
async fetchCustomerList(params = {}, forceRefresh = false) {
// 如果强制刷新或缓存无效,则重新请求
if (forceRefresh || !this.isCacheValid) {
this.loading = true
try {
// 请求全部数据(不传 statusList 参数)
const res = await getCustomerList({})
// API返回格式: { total: number, rows: array }
let customerList = []
if (res && res.rows && Array.isArray(res.rows)) {
customerList = res.rows
} else if (res && Array.isArray(res)) {
customerList = res
}
// 更新缓存
this.allCustomers = customerList
this.cacheTimestamp = Date.now()
this.lastParams = params
return customerList
} catch (error) {
console.error('获取客户列表失败:', error)
throw error
} finally {
this.loading = false
}
}
// 使用缓存数据
return this.allCustomers
},
/**
* 根据筛选条件获取客户列表优先使用缓存
* @param {Object} params - 请求参数包含 statusList 等筛选条件
* @param {boolean} forceRefresh - 是否强制刷新
* @returns {Promise<Array>} 返回筛选后的客户列表
*/
async getCustomerListByFilter(params = {}, forceRefresh = false) {
// 先确保有缓存数据
await this.fetchCustomerList({}, forceRefresh)
// 如果有筛选条件,进行前端筛选
if (params.statusList && Array.isArray(params.statusList) && params.statusList.length > 0) {
const status = params.statusList[0] // 取第一个状态
return this.getFilteredCustomers(status)
}
// 返回全部数据
return this.allCustomers
},
/**
* 清除缓存
*/
clearCache() {
this.allCustomers = []
this.cacheTimestamp = null
this.lastParams = null
},
/**
* 更新单个客户信息用于编辑后更新缓存
* @param {string} customerId - 客户ID
* @param {Object} updatedData - 更新的数据
*/
updateCustomer(customerId, updatedData) {
const index = this.allCustomers.findIndex(c => c.id === customerId)
if (index !== -1) {
this.allCustomers[index] = { ...this.allCustomers[index], ...updatedData }
}
},
/**
* 添加新客户到缓存用于新增后更新缓存
* @param {Object} newCustomer - 新客户数据
*/
addCustomer(newCustomer) {
this.allCustomers.unshift(newCustomer)
},
/**
* 删除客户用于删除后更新缓存
* @param {string} customerId - 客户ID
*/
removeCustomer(customerId) {
const index = this.allCustomers.findIndex(c => c.id === customerId)
if (index !== -1) {
this.allCustomers.splice(index, 1)
}
}
}
})