feat(dealer): 实现客户报备功能

- 新增客户报备页面,包括表单提交和审核状态显示
- 修改客户列表页面,增加签约和取消操作- 更新客户状态标签样式
- 调整API基础URL
This commit is contained in:
2025-09-03 11:57:23 +08:00
parent 0b43a3bc92
commit 3600c1dfba
7 changed files with 305 additions and 33 deletions

View File

@@ -1,27 +1,29 @@
import React, {useState, useEffect, useCallback} from 'react'
import {useState, useEffect, useCallback} from 'react'
import {View, Text} from '@tarojs/components'
import {Loading, Tabs, TabPane, Tag} from '@nutui/nutui-react-taro'
import Taro from '@tarojs/taro'
import {Loading, Space, Tabs, TabPane, Tag, Button} from '@nutui/nutui-react-taro'
import {Phone} from '@nutui/icons-react-taro'
import {pageUsers} from "@/api/system/user";
import type {User as UserType} from "@/api/system/user/model";
import type {ShopDealerApply, ShopDealerApply as UserType} from "@/api/shop/shopDealerApply/model";
import {
CustomerStatus,
getStatusText,
getStatusTagType,
getRandomStatus,
getStatusOptions
} from '@/utils/customerStatus';
import FixedButton from "@/components/FixedButton";
import navTo from "@/utils/common";
import {pageShopDealerApply, updateShopDealerApply} from "@/api/shop/shopDealerApply";
// 扩展User类型添加客户状态
interface CustomerUser extends UserType {
customerStatus?: CustomerStatus;
}
const CustomerManagement: React.FC = () => {
const CustomerIndex = () => {
const [list, setList] = useState<CustomerUser[]>([])
const [loading, setLoading] = useState<boolean>(false)
const [activeTab, setActiveTab] = useState<CustomerStatus>('all')
const [searchValue, setSearchValue] = useState<string>('')
const [searchValue, _] = useState<string>('')
// Tab配置
const tabList = getStatusOptions();
@@ -30,15 +32,24 @@ const CustomerManagement: React.FC = () => {
const fetchCustomerData = useCallback(async () => {
setLoading(true);
try {
// 获取用户列表status: 0 表示正常状态
const res = await pageUsers({ status: 0 });
const res = await pageShopDealerApply({});
if (res?.list) {
// 为每个用户添加随机的客户状态(实际项目中应该从后端获取真实状态)
const customersWithStatus: CustomerUser[] = res.list.map(user => ({
...user,
customerStatus: getRandomStatus() // 临时使用随机状态,实际应该从数据库获取
}));
setList(customersWithStatus);
list.map(d => {
if(d.applyStatus == 10){
d.customerStatus = 'pending'
}
if(d.applyStatus == 20){
d.customerStatus = 'signed'
}
if(d.applyStatus == 30){
d.customerStatus = 'cancelled'
}
return {
...d,
customerStatus: d.applyStatus == 10 ? 'pending' : 'signed'
}
})
setList(res.list);
}
} catch (error) {
console.error('获取客户数据失败:', error);
@@ -48,13 +59,18 @@ const CustomerManagement: React.FC = () => {
}, []);
// 根据当前Tab和搜索条件筛选数据
const getFilteredList = () => {
console.log('TABS',activeTab)
let filteredList = list;
// 按状态筛选
if (activeTab !== 'all') {
console.log(filteredList,'customerStatus')
filteredList.map(d => {
console.log(d.applyStatus)
})
filteredList = filteredList.filter(customer => customer.customerStatus === activeTab);
}
@@ -63,9 +79,9 @@ const CustomerManagement: React.FC = () => {
const keyword = searchValue.trim().toLowerCase();
filteredList = filteredList.filter(customer =>
(customer.realName && customer.realName.toLowerCase().includes(keyword)) ||
(customer.nickname && customer.nickname.toLowerCase().includes(keyword)) ||
(customer.username && customer.username.toLowerCase().includes(keyword)) ||
(customer.phone && customer.phone.includes(keyword)) ||
(customer.dealerName && customer.dealerName.toLowerCase().includes(keyword)) ||
(customer.dealerCode && customer.dealerCode.toLowerCase().includes(keyword)) ||
(customer.mobile && customer.mobile.includes(keyword)) ||
(customer.userId && customer.userId.toString().includes(keyword))
);
}
@@ -91,6 +107,16 @@ const CustomerManagement: React.FC = () => {
return counts;
};
// 取消操作
const handleCancel = (customer: ShopDealerApply) => {
updateShopDealerApply({
...customer,
applyStatus: 30
}).then(r => {
console.log(r)
})
};
// 初始化数据
useEffect(() => {
fetchCustomerData();
@@ -103,7 +129,7 @@ const CustomerManagement: React.FC = () => {
<View className="flex-1">
<View className="flex items-center justify-between mb-1">
<Text className="font-semibold text-gray-800 mr-2">
{customer.realName || customer.nickname || customer.username}
{customer.realName || customer.dealerName || customer.dealerCode}
</Text>
{customer.customerStatus && (
<Tag type={getStatusTagType(customer.customerStatus)}>
@@ -112,16 +138,37 @@ const CustomerManagement: React.FC = () => {
)}
</View>
<View className="flex items-center mb-1">
<Phone size={12} className="mr-1" />
<Text className="text-xs text-gray-500">
{customer.phone || '未填写'}
</Text>
<Space direction="vertical">
<Text className="text-xs text-gray-500">{customer.realName}</Text>
<Text className="text-xs text-gray-500">{customer.mobile}<Phone size={12}
className="ml-1 text-green-500"/></Text>
</Space>
</View>
<Text className="text-xs text-gray-500">
{customer.createTime}
{customer.createTime}
</Text>
</View>
</View>
{/* 跟进中状态显示操作按钮 */}
{customer.applyStatus === 10 && (
<Space className="flex justify-end">
<Button
size="small"
onClick={() => navTo(`/dealer/customer/add?id=${customer.applyId}`, true)}
style={{marginRight: '8px', backgroundColor: '#52c41a', color: 'white'}}
>
</Button>
<Button
size="small"
onClick={() => handleCancel(customer)}
style={{backgroundColor: '#ff4d4f', color: 'white'}}
>
</Button>
</Space>
)}
</View>
);
@@ -131,10 +178,10 @@ const CustomerManagement: React.FC = () => {
if (loading) {
return (
<View className="flex items-center justify-center py-8">
<Loading />
<Space className="flex items-center justify-center py-8">
<Loading/>
<Text className="text-gray-500 mt-2">...</Text>
</View>
</Space>
);
}
@@ -155,6 +202,7 @@ const CustomerManagement: React.FC = () => {
return (
<View className="min-h-screen bg-gray-50">
{/* 顶部Tabs */}
<View className="bg-white">
<Tabs
@@ -177,8 +225,10 @@ const CustomerManagement: React.FC = () => {
{/* 客户列表 */}
{renderCustomerList()}
<FixedButton text={'客户报备'} onClick={() => Taro.navigateTo({url: '/dealer/customer/add'})}/>
</View>
);
};
export default CustomerManagement;
export default CustomerIndex;