feat(customer): 添加客户详情和邀请好友功能
- 新增客户详情页面,包括公司信息、合同信息、企业信息和联系记录 - 添加邀请好友功能,包括二维码生成、邀请记录和统计图表 - 优化导航栏和首页网格组件,支持跳转到新页面- 调整 app.config.ts,添加新页面的路由配置
This commit is contained in:
279
src/pages/customer/list.tsx
Normal file
279
src/pages/customer/list.tsx
Normal file
@@ -0,0 +1,279 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro';
|
||||
import {View, Text} from '@tarojs/components';
|
||||
import {Space, Tabs, Button, Empty} from '@nutui/nutui-react-taro';
|
||||
import {Phone} from '@nutui/icons-react-taro';
|
||||
import './list.scss';
|
||||
|
||||
// 客户数据类型定义
|
||||
interface Customer {
|
||||
id: string;
|
||||
companyName: string;
|
||||
contactPerson: string;
|
||||
phone: string;
|
||||
address: string;
|
||||
addTime: string;
|
||||
status: 'pending' | 'confirmed' | 'cancelled';
|
||||
}
|
||||
|
||||
const CustomerList = () => {
|
||||
const [statusBarHeight, setStatusBarHeight] = useState<number>(0);
|
||||
const [activeTab, setActiveTab] = useState<string>('all');
|
||||
const [customers, setCustomers] = useState<Customer[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
// 模拟客户数据
|
||||
const mockCustomers: Customer[] = [
|
||||
{
|
||||
id: '1',
|
||||
companyName: '广州雅虎信息科技公司',
|
||||
contactPerson: 'XXX',
|
||||
phone: '13882223433',
|
||||
address: '广西南宁市良庆区五象大道401号五象新城1号楼1226室XXXXXX',
|
||||
addTime: '2025-08-15 10:23:33',
|
||||
status: 'pending'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
companyName: '广州雅虎信息科技公司',
|
||||
contactPerson: 'XXX',
|
||||
phone: '13882223433',
|
||||
address: '广西南宁市良庆区五象大道401号五象新城1号楼1226室XXXXXX',
|
||||
addTime: '2025-08-15 10:23:33',
|
||||
status: 'confirmed'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
companyName: '广州雅虎信息科技公司',
|
||||
contactPerson: 'XXX',
|
||||
phone: '13882223433',
|
||||
address: '广西南宁市良庆区五象大道401号五象新城1号楼1226室XXXXXX',
|
||||
addTime: '2025-08-15 10:23:33',
|
||||
status: 'cancelled'
|
||||
}
|
||||
];
|
||||
|
||||
const tabList = [
|
||||
{title: '全部', value: 'all'},
|
||||
{title: '跟进中', value: 'pending'},
|
||||
{title: '已签约', value: 'confirmed'},
|
||||
{title: '已取消', value: 'cancelled'}
|
||||
];
|
||||
|
||||
const reload = async () => {
|
||||
setLoading(true);
|
||||
// 模拟API调用
|
||||
setTimeout(() => {
|
||||
setCustomers(mockCustomers);
|
||||
setLoading(false);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const getFilteredCustomers = () => {
|
||||
if (activeTab === 'all') {
|
||||
return customers;
|
||||
}
|
||||
return customers.filter(customer => customer.status === activeTab);
|
||||
};
|
||||
|
||||
const getStatusText = (status: string) => {
|
||||
switch (status) {
|
||||
case 'pending':
|
||||
return '跟进中';
|
||||
case 'confirmed':
|
||||
return '已签约';
|
||||
case 'cancelled':
|
||||
return '已取消';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusColor = (status: string) => {
|
||||
switch (status) {
|
||||
case 'pending':
|
||||
return '#ff6b35';
|
||||
case 'confirmed':
|
||||
return '#52c41a';
|
||||
case 'cancelled':
|
||||
return '#999';
|
||||
default:
|
||||
return '#999';
|
||||
}
|
||||
};
|
||||
|
||||
const handleCall = (phone: string) => {
|
||||
Taro.makePhoneCall({
|
||||
phoneNumber: phone
|
||||
});
|
||||
};
|
||||
|
||||
const handleAction = (customer: Customer, action: 'sign' | 'cancel' | 'detail') => {
|
||||
switch (action) {
|
||||
case 'sign':
|
||||
// 跳转到签约页面
|
||||
Taro.navigateTo({
|
||||
url: `/pages/customer/sign?customerId=${customer.id}`
|
||||
});
|
||||
break;
|
||||
case 'cancel':
|
||||
Taro.showModal({
|
||||
title: '确认取消',
|
||||
content: '确定要取消该客户吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 这里应该调用取消客户的API
|
||||
Taro.showToast({
|
||||
title: '已取消',
|
||||
icon: 'success'
|
||||
});
|
||||
// 刷新列表
|
||||
reload().then();
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'detail':
|
||||
// 跳转到客户详情页面
|
||||
Taro.navigateTo({
|
||||
url: `/pages/customer/detail?customerId=${customer.id}`
|
||||
});
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleReport = () => {
|
||||
// 跳转到邀请页面
|
||||
Taro.navigateTo({
|
||||
url: '/pages/customer/invite'
|
||||
});
|
||||
};
|
||||
|
||||
const handleTrading = () => {
|
||||
// 跳转到入市交易页面
|
||||
Taro.navigateTo({
|
||||
url: '/pages/customer/trading'
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
Taro.getSystemInfo({
|
||||
success: (res) => {
|
||||
setStatusBarHeight(Number(res.statusBarHeight));
|
||||
},
|
||||
});
|
||||
reload().then();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View className="customer-list-page">
|
||||
{/* 头部背景 */}
|
||||
<View className="header-bg" style={{
|
||||
height: '180px'
|
||||
}} />
|
||||
|
||||
{/* 标签页 */}
|
||||
<View className="tabs-container">
|
||||
<Tabs
|
||||
value={activeTab}
|
||||
onChange={(value) => setActiveTab(value as string)}
|
||||
>
|
||||
{tabList.map(tab => (
|
||||
<Tabs.TabPane key={tab.value} title={tab.title} value={tab.value} />
|
||||
))}
|
||||
</Tabs>
|
||||
</View>
|
||||
|
||||
{/* 客户列表 */}
|
||||
<View className="customer-list">
|
||||
{loading ? (
|
||||
<View className="loading-container">
|
||||
<Text>加载中...</Text>
|
||||
</View>
|
||||
) : getFilteredCustomers().length > 0 ? (
|
||||
getFilteredCustomers().map((customer) => (
|
||||
<View key={customer.id} className="customer-item">
|
||||
<View className="customer-header">
|
||||
<Text className="company-name">{customer.companyName}</Text>
|
||||
<Text
|
||||
className="status-tag"
|
||||
style={{color: getStatusColor(customer.status)}}
|
||||
>
|
||||
{getStatusText(customer.status)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View className="customer-info">
|
||||
<View className="info-row">
|
||||
<Text className="label">联系人:</Text>
|
||||
<Text className="value">{customer.contactPerson}</Text>
|
||||
<Text className="label contact-label">联系电话:</Text>
|
||||
<Text className="value">{customer.phone}</Text>
|
||||
<Phone
|
||||
size={14}
|
||||
className={'text-green-500'}
|
||||
onClick={() => handleCall(customer.phone)}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View className="address-row">
|
||||
<Text className="label">地址:</Text>
|
||||
<Text className="address">{customer.address}</Text>
|
||||
</View>
|
||||
|
||||
<View className="time-row">
|
||||
<Text className="time">添加时间:{customer.addTime}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<View className="action-buttons">
|
||||
{customer.status === 'pending' && (
|
||||
<Space>
|
||||
<Button
|
||||
className="action-btn sign-btn"
|
||||
size="small"
|
||||
onClick={() => handleAction(customer, 'sign')}
|
||||
>
|
||||
签约
|
||||
</Button>
|
||||
<Button
|
||||
className="action-btn cancel-btn"
|
||||
size="small"
|
||||
onClick={() => handleAction(customer, 'cancel')}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
</Space>
|
||||
)}
|
||||
{customer.status === 'confirmed' && (
|
||||
<Button
|
||||
className="action-btn detail-btn"
|
||||
size="small"
|
||||
onClick={() => handleAction(customer, 'detail')}
|
||||
>
|
||||
查看详情
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
))
|
||||
) : (
|
||||
<Empty description="暂无客户数据" />
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* 底部邀请好友按钮 */}
|
||||
<View className="fixed-bottom">
|
||||
<Button
|
||||
className="report-btn"
|
||||
onClick={handleReport}
|
||||
>
|
||||
客户报备
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomerList;
|
||||
Reference in New Issue
Block a user