- 移除客户添加表单中公司名称输入框的maxLength限制 - 更新联系方式1标签为联系方式 - 在提现管理中引入Image组件并替换原生img标签 - 实现上传打款凭证的新逻辑,支持选择和上传图片 - 配置开发环境API基础URL为本地地址 - 修改订单查询条件,管理员可查看所有用户订单 - 注释掉不再使用的getResourceId方法 - 启用request.ts中的本地开发环境baseUrl配置
454 lines
14 KiB
TypeScript
454 lines
14 KiB
TypeScript
import React, {useState, useEffect, useCallback} from 'react'
|
||
import {View, Text, ScrollView} from '@tarojs/components'
|
||
import {Empty, PullToRefresh, Space, Loading, DatePicker, Button, Picker} from '@nutui/nutui-react-taro'
|
||
import {ArrowDown} from '@nutui/icons-react-taro'
|
||
import Taro from '@tarojs/taro'
|
||
import {pageShopDealerOrder} from '@/api/shop/shopDealerOrder'
|
||
import {useDealerUser} from '@/hooks/useDealerUser'
|
||
import type {ShopDealerOrder} from '@/api/shop/shopDealerOrder/model'
|
||
import {useUser} from "@/hooks/useUser";
|
||
import {pageShopDealerReferee} from "@/api/shop/shopDealerReferee";
|
||
|
||
interface OrderWithDetails extends ShopDealerOrder {
|
||
orderNo?: string
|
||
customerName?: string
|
||
userCommission?: string
|
||
}
|
||
|
||
interface PickerOption {
|
||
text: string | number
|
||
value: string | number
|
||
disabled?: boolean
|
||
children?: PickerOption[]
|
||
className?: string | number
|
||
}
|
||
|
||
const DealerOrder: React.FC = () => {
|
||
const [loading, setLoading] = useState<boolean>(false)
|
||
const d = new Date()
|
||
const currMonth = `${d.getFullYear()}${d.getMonth() + 1}`;
|
||
const currDate = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`;
|
||
const [date, setDate] = useState(currMonth)
|
||
const [show1, setShow1] = useState(false)
|
||
const [refreshing, setRefreshing] = useState<boolean>(false)
|
||
const [loadingMore, setLoadingMore] = useState<boolean>(false)
|
||
const [orders, setOrders] = useState<OrderWithDetails[]>([])
|
||
const [currentPage, setCurrentPage] = useState<number>(1)
|
||
const [hasMore, setHasMore] = useState<boolean>(true)
|
||
const [users, setUsers] = useState<any[]>([])
|
||
const [users2, setUsers2] = useState<any[]>([])
|
||
const [visible1, setVisible1] = useState(false)
|
||
const [text1, setText1] = useState('')
|
||
const [selectedUserId, setSelectedUserId] = useState<number | undefined>(undefined)
|
||
const [visible2, setVisible2] = useState(false)
|
||
const [text2, setText2] = useState('')
|
||
const [selectedFirstUserId, setSelectedFirstUserId] = useState<number | undefined>(undefined)
|
||
const [visible3, setVisible3] = useState(false)
|
||
// const [text3, setText3] = useState('')
|
||
const [selectedSecondUserId, setSelectedSecondUserId] = useState<number | undefined>(undefined)
|
||
|
||
|
||
const {dealerUser} = useDealerUser()
|
||
const {user} = useUser()
|
||
|
||
// 获取订单数据
|
||
const fetchOrders = useCallback(async (page: number = 1, isRefresh: boolean = false) => {
|
||
if (!dealerUser?.userId) return
|
||
|
||
try {
|
||
if (isRefresh) {
|
||
setRefreshing(true)
|
||
} else if (page === 1) {
|
||
setLoading(true)
|
||
} else {
|
||
setLoadingMore(true)
|
||
}
|
||
|
||
let where = {
|
||
userId: selectedUserId,
|
||
firstUserId: selectedSecondUserId,
|
||
secondUserId: selectedSecondUserId,
|
||
isInvalid: 0,
|
||
isSettled: 1,
|
||
resourceId: user?.userId,
|
||
month: date,
|
||
page,
|
||
limit: 10
|
||
};
|
||
if (hasRole('superAdmin') || hasRole('admin')) {
|
||
console.log('>>>>>>>>>>>>是管理员')
|
||
where = {...where, resourceId: undefined}
|
||
}
|
||
if(selectedUserId){
|
||
where = {...where,userId: selectedUserId}
|
||
}
|
||
if(selectedFirstUserId){
|
||
where = {...where,secondUserId: selectedFirstUserId}
|
||
}
|
||
|
||
const result = await pageShopDealerOrder(where)
|
||
|
||
if (result?.list) {
|
||
const newOrders = result.list.map(order => ({
|
||
...order,
|
||
orderNo: `${order.orderNo}`,
|
||
customerName: `用户${order.userId}`,
|
||
userCommission: order.firstMoney || '0.00'
|
||
}))
|
||
|
||
if (page === 1) {
|
||
setOrders(newOrders)
|
||
} else {
|
||
setOrders(prev => [...prev, ...newOrders])
|
||
}
|
||
|
||
setHasMore(newOrders.length === 10)
|
||
setCurrentPage(page)
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('获取分销订单失败:', error)
|
||
Taro.showToast({
|
||
title: '获取订单失败',
|
||
icon: 'error'
|
||
})
|
||
} finally {
|
||
setLoading(false)
|
||
setRefreshing(false)
|
||
setLoadingMore(false)
|
||
}
|
||
}, [dealerUser?.userId, date, selectedUserId, selectedFirstUserId, selectedSecondUserId])
|
||
|
||
// 下拉刷新
|
||
const handleRefresh = async () => {
|
||
await fetchOrders(1, true)
|
||
}
|
||
|
||
// 加载更多
|
||
const handleLoadMore = async () => {
|
||
if (!loadingMore && hasMore) {
|
||
await fetchOrders(currentPage + 1)
|
||
}
|
||
}
|
||
|
||
// const getResourceId = () => {
|
||
// if (hasRole('superAdmin')) {
|
||
// return undefined
|
||
// }
|
||
// if (hasRole('admin')) {
|
||
// return user?.userId
|
||
// }
|
||
// return user?.userId;
|
||
// }
|
||
|
||
// 检查是否有特定角色
|
||
const hasRole = (roleCode: string) => {
|
||
if (!user || !user.roles) {
|
||
return false;
|
||
}
|
||
return user.roles.some(role => role.roleCode === roleCode);
|
||
}
|
||
|
||
const confirmPicker1 = (
|
||
options: PickerOption[],
|
||
values: (string | number)[]
|
||
) => {
|
||
if(values && values.length > 0){
|
||
const userId = Number(values[0])
|
||
options.forEach((option: any) => {
|
||
setText1(`${option.text}`)
|
||
})
|
||
// 清空其他两个筛选条件
|
||
setSelectedFirstUserId(undefined)
|
||
setSelectedSecondUserId(undefined)
|
||
setText2('')
|
||
// setText3('')
|
||
// 设置业务员筛选条件
|
||
setSelectedUserId(userId)
|
||
// 关闭选择器
|
||
setVisible1(false)
|
||
}
|
||
}
|
||
const confirmPicker2 = (
|
||
options: PickerOption[],
|
||
values: (string | number)[]
|
||
) => {
|
||
if(values && values.length > 0){
|
||
const firstUserId = Number(values[0])
|
||
options.forEach((option: any) => {
|
||
setText2(`${option.text}`)
|
||
})
|
||
// 清空其他两个筛选条件
|
||
// setSelectedUserId(undefined)
|
||
// setSelectedSecondUserId(undefined)
|
||
// setText1('')
|
||
// setText3('')
|
||
// 设置渠道一筛选条件
|
||
setSelectedFirstUserId(firstUserId)
|
||
// 关闭选择器
|
||
setVisible2(false)
|
||
}
|
||
}
|
||
const confirmPicker3 = (
|
||
_: PickerOption[],
|
||
values: (string | number)[]
|
||
) => {
|
||
if(values && values.length > 0){
|
||
const secondUserId = Number(values[0])
|
||
// options.forEach((option: any) => {
|
||
// setText3(`${option.text}`)
|
||
// })
|
||
// 清空其他两个筛选条件
|
||
setSelectedUserId(undefined)
|
||
setSelectedFirstUserId(undefined)
|
||
setText1('')
|
||
setText2('')
|
||
// 设置渠道二筛选条件
|
||
setSelectedSecondUserId(secondUserId)
|
||
// 关闭选择器
|
||
setVisible3(false)
|
||
}
|
||
}
|
||
|
||
const getStatusText = (isSettled?: number, isInvalid?: number) => {
|
||
if (isInvalid === 1) return '未签约'
|
||
if (isSettled === 1) return '已结算'
|
||
return '待结算'
|
||
}
|
||
|
||
function fetchUsers() {
|
||
pageShopDealerReferee({
|
||
dealerId: selectedFirstUserId || Taro.getStorageSync('UserId'),
|
||
isAdmin: true,
|
||
limit: 100
|
||
}).then(res => {
|
||
const data = res?.list.map(d => {
|
||
return {
|
||
text: d.nickname,
|
||
value: d.userId,
|
||
disabled: false,
|
||
children: [],
|
||
className: ''
|
||
}
|
||
})
|
||
setUsers(data || [])
|
||
})
|
||
pageShopDealerReferee({
|
||
dealerId: selectedUserId || Taro.getStorageSync('UserId'),
|
||
limit: 100
|
||
}).then(res => {
|
||
const data = res?.list.map(d => {
|
||
return {
|
||
text: d.nickname,
|
||
value: d.userId,
|
||
disabled: false,
|
||
children: [],
|
||
className: ''
|
||
}
|
||
})
|
||
setUsers2(data || [])
|
||
})
|
||
}
|
||
|
||
// 初始化加载数据
|
||
useEffect(() => {
|
||
if (dealerUser?.userId) {
|
||
fetchOrders(1).then()
|
||
}
|
||
fetchUsers()
|
||
}, [fetchOrders, date])
|
||
|
||
useEffect(() => {
|
||
},[])
|
||
|
||
const renderOrderItem = (order: OrderWithDetails) => (
|
||
<View key={order.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm">
|
||
<View className="flex justify-between items-start mb-1">
|
||
<Text className="font-semibold text-gray-800">
|
||
订单号:{order.orderNo}
|
||
</Text>
|
||
</View>
|
||
|
||
<View className="flex justify-between items-center mb-1">
|
||
<Text className="text-sm text-gray-400">
|
||
客户名称:{order.title}
|
||
</Text>
|
||
</View>
|
||
|
||
{/* 添加收益用户信息显示 */}
|
||
<View className="flex justify-between items-center mb-1 mt-2">
|
||
<Text className="text-sm text-gray-400">
|
||
收益计算
|
||
</Text>
|
||
</View>
|
||
<View className="mb-1">
|
||
{/* 一级佣金30 */}
|
||
{(hasRole('superAdmin') || hasRole('admin') || Taro.getStorageSync('UserId') != order.thirdUserId) && (
|
||
<>
|
||
{Taro.getStorageSync('UserId') != order.secondUserId && (
|
||
<>
|
||
{(order.firstNickname || order.firstUserId) && (
|
||
<Text className="text-sm text-gray-400 block">
|
||
一级佣金:{order.firstNickname || `用户${order.firstUserId}`} (¥{order.firstMoney || '0.00'})
|
||
</Text>
|
||
)}
|
||
</>
|
||
)}
|
||
{(order.secondUserId || order.secondUserId) && (
|
||
<Text className="text-sm text-gray-400 block">
|
||
二级佣金:{order.secondNickname || `用户${order.secondUserId}`} (¥{order.secondMoney || '0.00'})
|
||
</Text>
|
||
)}
|
||
</>
|
||
)}
|
||
|
||
{/* 三级分销商 */}
|
||
{(order.thirdUserId !== undefined && order.thirdUserId > 0) && (
|
||
<Text className="text-sm text-gray-400 block">
|
||
三级佣金:{order.thirdNickname || `用户${order.thirdUserId}`} (¥{order.thirdMoney || '0.00'})
|
||
</Text>
|
||
)}
|
||
|
||
</View>
|
||
|
||
<View className="flex justify-between items-center mt-2">
|
||
<Text className="text-sm text-gray-400">
|
||
结算电量:{order.degreePrice}
|
||
</Text>
|
||
<Text className="text-sm text-gray-400">
|
||
结算金额:{order.settledPrice}
|
||
</Text>
|
||
</View>
|
||
|
||
<View className="flex justify-between items-center mb-1">
|
||
<Text className="text-sm text-gray-400">
|
||
单价:{order.price}
|
||
</Text>
|
||
<Text className="text-sm text-gray-400">
|
||
税费:{order.rate}
|
||
</Text>
|
||
</View>
|
||
|
||
<View className="flex justify-between items-center mb-1">
|
||
<Text className="text-sm text-gray-400">
|
||
实发金额:{order.payPrice}
|
||
</Text>
|
||
<Text className="text-sm text-gray-400">
|
||
结算月份:{order.month}
|
||
</Text>
|
||
</View>
|
||
|
||
<View className="flex justify-between items-center mb-1">
|
||
<Text className="text-sm text-gray-400">
|
||
结算状态:{getStatusText(order.isSettled, order.isInvalid)}
|
||
</Text>
|
||
<Text className="text-sm text-gray-400">
|
||
{order.settleTime}
|
||
</Text>
|
||
</View>
|
||
|
||
</View>
|
||
)
|
||
|
||
return (
|
||
<View className="min-h-screen bg-gray-50">
|
||
<PullToRefresh
|
||
onRefresh={handleRefresh}
|
||
disabled={refreshing}
|
||
pullingText="下拉刷新"
|
||
canReleaseText="释放刷新"
|
||
refreshingText="刷新中..."
|
||
completeText="刷新完成"
|
||
>
|
||
<ScrollView
|
||
scrollY
|
||
className={'h-screen'}
|
||
onScrollToLower={handleLoadMore}
|
||
lowerThreshold={50}
|
||
>
|
||
{/*筛选工具条*/}
|
||
<View
|
||
className={'p-4 flex items-center justify-between'}
|
||
>
|
||
<View className={'select-month'}>
|
||
<Text className={'text-sm mx-1'} onClick={() => setShow1(true)}>{date ? `${date}` : '请选择'}</Text>
|
||
<ArrowDown size={10} className={'text-gray-400'} onClick={() => setShow1(true)}/>
|
||
</View>
|
||
<Space className={'select-user'}>
|
||
<Button size={'mini'} onClick={() => setVisible1(!visible1)}>{text1 || '业务员'}</Button>
|
||
{/*{selectedUserId && <Button size={'mini'} onClick={() => setVisible2(!visible2)}>{text2 || '渠道员'}</Button>}*/}
|
||
<Button size={'mini'} onClick={() => setVisible2(!visible3)}>{text2 || '渠道员'}</Button>
|
||
</Space>
|
||
</View>
|
||
{/*账单列表*/}
|
||
<View className="px-4">
|
||
{loading && orders.length === 0 ? (
|
||
<View className="text-center py-8">
|
||
<Loading/>
|
||
<Text className="text-gray-500 mt-2">加载中...</Text>
|
||
</View>
|
||
) : orders.length > 0 ? (
|
||
<>
|
||
{orders.map(renderOrderItem)}
|
||
{loadingMore && (
|
||
<View className="text-center py-4">
|
||
<Loading/>
|
||
<Text className="text-gray-500 mt-1 text-sm">加载更多...</Text>
|
||
</View>
|
||
)}
|
||
{!hasMore && orders.length > 0 && (
|
||
<View className="text-center py-4">
|
||
<Text className="text-gray-400 text-sm">没有更多数据了</Text>
|
||
</View>
|
||
)}
|
||
</>
|
||
) : (
|
||
<Empty description="暂无电费订单" style={{
|
||
backgroundColor: 'transparent'
|
||
}}/>
|
||
)}
|
||
</View>
|
||
</ScrollView>
|
||
</PullToRefresh>
|
||
<DatePicker
|
||
title="日期选择"
|
||
visible={show1}
|
||
pickerProps={{
|
||
popupProps: {zIndex: 1220},
|
||
}}
|
||
type={'year-month'}
|
||
defaultValue={new Date(`${currDate}`)}
|
||
showChinese
|
||
onCancel={() => setShow1(false)}
|
||
onConfirm={(_, values) => {
|
||
setShow1(false)
|
||
setDate(`${values[0]}${values[1]}`)
|
||
}}
|
||
/>
|
||
<Picker
|
||
title="请选择"
|
||
visible={visible1}
|
||
options={users}
|
||
onConfirm={(list, values) => confirmPicker1(list, values)}
|
||
onClose={() => setVisible1(false)}
|
||
/>
|
||
<Picker
|
||
title="请选择"
|
||
visible={visible2}
|
||
options={users2}
|
||
onConfirm={(list, values) => confirmPicker2(list, values)}
|
||
onClose={() => setVisible2(false)}
|
||
/>
|
||
<Picker
|
||
title="请选择"
|
||
visible={visible3}
|
||
options={users}
|
||
onConfirm={(list, values) => confirmPicker3(list, values)}
|
||
onClose={() => setVisible3(false)}
|
||
/>
|
||
</View>
|
||
)
|
||
}
|
||
|
||
export default DealerOrder
|