270 lines
6.1 KiB
JavaScript
270 lines
6.1 KiB
JavaScript
// pages/customer/index.js
|
|
const API = require('../../utils/api.js')
|
|
|
|
// 性别映射
|
|
const SEX_MAP = {
|
|
male: { label: '男', text: '先生' },
|
|
female: { label: '女', text: '女士' },
|
|
other: { label: '其他', text: '' },
|
|
'': { label: '未知', text: '' }
|
|
}
|
|
|
|
Page({
|
|
data: {
|
|
// 搜索相关
|
|
searchKey: '',
|
|
// 客户列表
|
|
customerList: [],
|
|
// 分页
|
|
page: 1,
|
|
pageSize: 10,
|
|
hasMore: true,
|
|
// 加载状态
|
|
isLoading: false,
|
|
isLoadingMore: false,
|
|
isRefreshing: false,
|
|
// 统计数据
|
|
stats: {
|
|
total: 0,
|
|
male: 0,
|
|
female: 0
|
|
}
|
|
},
|
|
|
|
onLoad(options) {
|
|
this.loadCustomerList();
|
|
},
|
|
|
|
onShow() {
|
|
// 页面显示时如果已有数据则刷新
|
|
if (this.data.customerList.length > 0) {
|
|
this.refreshData();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 格式化日期
|
|
*/
|
|
formatDate(dateStr) {
|
|
if (!dateStr) return '';
|
|
const date = new Date(dateStr);
|
|
const year = date.getFullYear();
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
return `${year}-${month}-${day}`;
|
|
},
|
|
|
|
/**
|
|
* 处理客户数据
|
|
*/
|
|
processCustomers(customers) {
|
|
return customers.map(customer => {
|
|
const profile = customer.profile || {};
|
|
const sexInfo = SEX_MAP[profile.sex] || SEX_MAP[''];
|
|
return {
|
|
...customer,
|
|
name: profile.name || '未知姓名',
|
|
mobile: profile.mobile || '暂无电话',
|
|
sex: profile.sex || '',
|
|
sexLabel: sexInfo.label,
|
|
sexText: sexInfo.text,
|
|
avatar: profile.avatar || '',
|
|
avatarText: profile.name ? profile.name[0].toUpperCase() : '客',
|
|
birth: profile.birth ? this.formatDate(profile.birth) : '',
|
|
createdAt: customer.meta?.createtime ? this.formatDate(customer.meta.createtime) : '',
|
|
locationText: this.getLocationText(customer)
|
|
};
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 获取位置文本
|
|
*/
|
|
getLocationText(customer) {
|
|
const location = customer.location || {};
|
|
if (location.province || location.city) {
|
|
return `${location.province || ''}${location.city || ''}`;
|
|
}
|
|
return '';
|
|
},
|
|
|
|
/**
|
|
* 计算统计数据
|
|
*/
|
|
calculateStats(customers) {
|
|
const stats = {
|
|
total: customers.length,
|
|
male: 0,
|
|
female: 0
|
|
};
|
|
|
|
customers.forEach(customer => {
|
|
const sex = customer.profile?.sex || '';
|
|
if (sex === 'male') stats.male++;
|
|
else if (sex === 'female') stats.female++;
|
|
});
|
|
|
|
return stats;
|
|
},
|
|
|
|
/**
|
|
* 加载客户列表
|
|
*/
|
|
loadCustomerList(isRefresh = false) {
|
|
if (this.data.isLoading || this.data.isLoadingMore) return;
|
|
|
|
const { page, pageSize, searchKey } = this.data;
|
|
this.setData({
|
|
isLoading: !isRefresh && page === 1,
|
|
isLoadingMore: isRefresh && page > 1
|
|
});
|
|
|
|
const params = {
|
|
page,
|
|
pageSize
|
|
};
|
|
|
|
if (searchKey && searchKey.trim()) {
|
|
params.keyword = searchKey.trim();
|
|
}
|
|
|
|
API.user.userList(params)
|
|
.then(res => {
|
|
if (res.code !== 0) {
|
|
wx.showToast({ title: res.message || '获取客户列表失败', icon: 'none' });
|
|
this.setData({ isLoading: false, isLoadingMore: false, isRefreshing: false });
|
|
return;
|
|
}
|
|
|
|
const data = res.data || {};
|
|
const list = data.users || [];
|
|
const total = data?.users?.length || 0;
|
|
|
|
const processedCustomers = this.processCustomers(list);
|
|
|
|
let allCustomers = isRefresh && page > 1
|
|
? [...this.data.customerList, ...processedCustomers]
|
|
: processedCustomers;
|
|
|
|
// 如果有搜索条件,在前端过滤
|
|
if (searchKey && searchKey.trim()) {
|
|
const keyword = searchKey.trim().toLowerCase();
|
|
allCustomers = allCustomers.filter(customer => {
|
|
return customer.name.toLowerCase().includes(keyword) ||
|
|
customer.mobile.includes(keyword);
|
|
});
|
|
}
|
|
|
|
const stats = this.calculateStats(allCustomers);
|
|
|
|
this.setData({
|
|
customerList: allCustomers,
|
|
stats,
|
|
isLoading: false,
|
|
isLoadingMore: false,
|
|
isRefreshing: false,
|
|
hasMore: allCustomers.length < total
|
|
});
|
|
})
|
|
.catch(err => {
|
|
console.error('获取客户列表失败', err);
|
|
wx.showToast({ title: '网络错误,请重试', icon: 'none' });
|
|
this.setData({ isLoading: false, isLoadingMore: false, isRefreshing: false });
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 刷新数据
|
|
*/
|
|
refreshData() {
|
|
this.setData({ page: 1, hasMore: true }, () => {
|
|
this.loadCustomerList();
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 搜索输入
|
|
*/
|
|
onSearchInput(e) {
|
|
this.setData({ searchKey: e.detail.value });
|
|
},
|
|
|
|
/**
|
|
* 搜索确认
|
|
*/
|
|
onSearch() {
|
|
this.setData({ page: 1, hasMore: true, customerList: [] }, () => {
|
|
this.loadCustomerList();
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 清除搜索
|
|
*/
|
|
onClearSearch() {
|
|
if (this.data.searchKey) {
|
|
this.setData({ searchKey: '', page: 1, hasMore: true, customerList: [] }, () => {
|
|
this.loadCustomerList();
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 客户详情
|
|
*/
|
|
onCustomerDetail(e) {
|
|
const { id } = e.currentTarget.dataset;
|
|
wx.navigateTo({
|
|
url: `/pages/customer/detail?id=${id}`
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 拨打电话
|
|
*/
|
|
onCallPhone(e) {
|
|
const { phone } = e.currentTarget.dataset;
|
|
if (!phone) {
|
|
wx.showToast({ title: '暂无电话号码', icon: 'none' });
|
|
return;
|
|
}
|
|
wx.makePhoneCall({
|
|
phoneNumber: phone,
|
|
fail: () => {
|
|
wx.showToast({ title: '拨打电话失败', icon: 'none' });
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 下拉刷新
|
|
*/
|
|
onPullDownRefresh() {
|
|
this.setData({ isRefreshing: true, page: 1, hasMore: true }, () => {
|
|
this.loadCustomerList();
|
|
});
|
|
wx.stopPullDownRefresh();
|
|
},
|
|
|
|
/**
|
|
* 上拉加载更多
|
|
*/
|
|
onReachBottom() {
|
|
if (!this.data.hasMore || this.data.isLoadingMore) return;
|
|
|
|
this.setData({ page: this.data.page + 1 }, () => {
|
|
this.loadCustomerList(true);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 用户点击右上角分享
|
|
*/
|
|
onShareAppMessage() {
|
|
return {
|
|
title: '客户管理',
|
|
path: '/pages/customer/index'
|
|
};
|
|
}
|
|
});
|