feat(dealer): 添加客户搜索功能并优化订单展示

- 在客户页面添加搜索栏,支持防抖搜索- 增加搜索结果统计展示-优化订单列表展示逻辑
- 调整订单状态文案及金额显示
- 更新收益统计标题- 添加订单备注字段支持
- 过滤已失效订单数据
This commit is contained in:
2025-10-02 09:52:55 +08:00
parent ae78a10b91
commit b0190247d9
4 changed files with 93 additions and 53 deletions

View File

@@ -30,6 +30,8 @@ export interface ShopDealerOrder {
isSettled?: number; isSettled?: number;
// 结算时间 // 结算时间
settleTime?: number; settleTime?: number;
// 订单备注
comments?: string;
// 商城ID // 商城ID
tenantId?: number; tenantId?: number;
// 创建时间 // 创建时间
@@ -47,5 +49,7 @@ export interface ShopDealerOrderParam extends PageParam {
secondUserId?: number; secondUserId?: number;
thirdUserId?: number; thirdUserId?: number;
userId?: number; userId?: number;
isInvalid?: number;
isSettled?: number;
keywords?: string; keywords?: string;
} }

View File

@@ -1,7 +1,7 @@
import {useState, useEffect, useCallback} from 'react' import {useState, useEffect, useCallback} from 'react'
import {View, Text} from '@tarojs/components' import {View, Text} from '@tarojs/components'
import Taro, {useDidShow} from '@tarojs/taro' import Taro, {useDidShow} from '@tarojs/taro'
import {Loading, InfiniteLoading, Empty, Space, Tabs, TabPane, Tag, Button} from '@nutui/nutui-react-taro' import {Loading, InfiniteLoading, Empty, Space, Tabs, TabPane, Tag, Button, SearchBar} from '@nutui/nutui-react-taro'
import {Phone, AngleDoubleLeft} from '@nutui/icons-react-taro' import {Phone, AngleDoubleLeft} from '@nutui/icons-react-taro'
import type {ShopDealerApply, ShopDealerApply as UserType} from "@/api/shop/shopDealerApply/model"; import type {ShopDealerApply, ShopDealerApply as UserType} from "@/api/shop/shopDealerApply/model";
import { import {
@@ -26,7 +26,8 @@ const CustomerIndex = () => {
const [list, setList] = useState<CustomerUser[]>([]) const [list, setList] = useState<CustomerUser[]>([])
const [loading, setLoading] = useState<boolean>(false) const [loading, setLoading] = useState<boolean>(false)
const [activeTab, setActiveTab] = useState<CustomerStatus>('all') const [activeTab, setActiveTab] = useState<CustomerStatus>('all')
const [searchValue, _] = useState<string>('') const [searchValue, setSearchValue] = useState<string>('')
const [displaySearchValue, setDisplaySearchValue] = useState<string>('')
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [hasMore, setHasMore] = useState(true) const [hasMore, setHasMore] = useState(true)
@@ -227,13 +228,22 @@ const CustomerIndex = () => {
} }
// 防抖搜索功能
useEffect(() => {
const timer = setTimeout(() => {
setDisplaySearchValue(searchValue);
}, 300); // 300ms 防抖
return () => clearTimeout(timer);
}, [searchValue]);
// 根据搜索条件筛选数据状态筛选已在API层面处理 // 根据搜索条件筛选数据状态筛选已在API层面处理
const getFilteredList = () => { const getFilteredList = () => {
let filteredList = list; let filteredList = list;
// 按搜索关键词筛选 // 按搜索关键词筛选
if (searchValue.trim()) { if (displaySearchValue.trim()) {
const keyword = searchValue.trim().toLowerCase(); const keyword = displaySearchValue.trim().toLowerCase();
filteredList = filteredList.filter(customer => filteredList = filteredList.filter(customer =>
(customer.realName && customer.realName.toLowerCase().includes(keyword)) || (customer.realName && customer.realName.toLowerCase().includes(keyword)) ||
(customer.dealerName && customer.dealerName.toLowerCase().includes(keyword)) || (customer.dealerName && customer.dealerName.toLowerCase().includes(keyword)) ||
@@ -466,10 +476,21 @@ const CustomerIndex = () => {
// 渲染客户列表 // 渲染客户列表
const renderCustomerList = () => { const renderCustomerList = () => {
const filteredList = getFilteredList(); const filteredList = getFilteredList();
const isSearching = displaySearchValue.trim().length > 0;
return ( return (
<View className="flex-1">
{/* 搜索结果统计 */}
{isSearching && (
<View className="bg-white px-4 py-2 border-b border-gray-100">
<Text className="text-sm text-gray-600">
"{displaySearchValue}" {filteredList.length}
</Text>
</View>
)}
<View className="p-4" style={{ <View className="p-4" style={{
height: '90vh', height: isSearching ? 'calc(90vh - 40px)' : '90vh',
overflowY: 'auto', overflowY: 'auto',
overflowX: 'hidden' overflowX: 'hidden'
}}> }}>
@@ -511,11 +532,25 @@ const CustomerIndex = () => {
)} )}
</InfiniteLoading> </InfiniteLoading>
</View> </View>
</View>
); );
}; };
return ( return (
<View className="min-h-screen bg-gray-50"> <View className="min-h-screen bg-gray-50">
{/* 搜索栏 */}
<View className="bg-white py-2 border-b border-gray-100">
<SearchBar
value={searchValue}
placeholder="搜索客户名称、手机号"
onChange={(value) => setSearchValue(value)}
onClear={() => {
setSearchValue('');
setDisplaySearchValue('');
}}
clearable
/>
</View>
{/* 顶部Tabs */} {/* 顶部Tabs */}
<View className="bg-white"> <View className="bg-white">

View File

@@ -129,7 +129,7 @@ const DealerIndex: React.FC = () => {
{dealerUser && ( {dealerUser && (
<View className="mx-4 -mt-6 rounded-xl p-4 relative z-10" style={cardGradients.elevated}> <View className="mx-4 -mt-6 rounded-xl p-4 relative z-10" style={cardGradients.elevated}>
<View className="mb-4"> <View className="mb-4">
<Text className="font-semibold text-gray-800"></Text> <Text className="font-semibold text-gray-800"></Text>
</View> </View>
<View className="grid grid-cols-3 gap-3"> <View className="grid grid-cols-3 gap-3">
<View className="text-center p-3 rounded-lg flex flex-col" style={{ <View className="text-center p-3 rounded-lg flex flex-col" style={{

View File

@@ -36,6 +36,7 @@ const DealerOrders: React.FC = () => {
} }
const result = await pageShopDealerOrder({ const result = await pageShopDealerOrder({
isInvalid: 0,
page, page,
limit: 10 limit: 10
}) })
@@ -91,7 +92,7 @@ const DealerOrders: React.FC = () => {
}, [fetchOrders]) }, [fetchOrders])
const getStatusText = (isSettled?: number, isInvalid?: number) => { const getStatusText = (isSettled?: number, isInvalid?: number) => {
if (isInvalid === 1) return '已失效' if (isInvalid === 1) return '未签约'
if (isSettled === 1) return '已结算' if (isSettled === 1) return '已结算'
return '待结算' return '待结算'
} }
@@ -106,7 +107,7 @@ const DealerOrders: React.FC = () => {
<View key={order.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm"> <View key={order.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm">
<View className="flex justify-between items-start mb-1"> <View className="flex justify-between items-start mb-1">
<Text className="font-semibold text-gray-800"> <Text className="font-semibold text-gray-800">
{order.orderNo}
</Text> </Text>
<Tag type={getStatusColor(order.isSettled, order.isInvalid)}> <Tag type={getStatusColor(order.isSettled, order.isInvalid)}>
{getStatusText(order.isSettled, order.isInvalid)} {getStatusText(order.isSettled, order.isInvalid)}
@@ -115,19 +116,19 @@ const DealerOrders: React.FC = () => {
<View className="flex justify-between items-center mb-1"> <View className="flex justify-between items-center mb-1">
<Text className="text-sm text-gray-400"> <Text className="text-sm text-gray-400">
¥{order.orderPrice || '0.00'} ¥{order.orderPrice || '0.00'}
</Text> </Text>
<Text className="text-sm text-orange-500 font-semibold"> <Text className="text-lg text-orange-500 font-semibold">
¥{order.userCommission} ¥{(Number(order.orderPrice) * 10).toFixed(2)}
</Text> </Text>
</View> </View>
<View className="flex justify-between items-center"> <View className="flex justify-between items-center">
<Text className="text-sm text-gray-400"> <Text className="text-sm text-gray-400">
{order.customerName} {order.comments}
</Text> </Text>
<Text className="text-sm text-gray-400"> <Text className="text-sm text-gray-400">
{order.createTime} {order.settleTime}
</Text> </Text>
</View> </View>
</View> </View>