经销商替换
This commit is contained in:
@@ -184,7 +184,7 @@ export default function CompanyPermissionsPage() {
|
|||||||
const getRoleInfo = (roleKey: string) => {
|
const getRoleInfo = (roleKey: string) => {
|
||||||
const roleMap = {
|
const roleMap = {
|
||||||
admin: { label: "总部管理员", icon: Shield, color: "bg-purple-100 text-purple-800" },
|
admin: { label: "总部管理员", icon: Shield, color: "bg-purple-100 text-purple-800" },
|
||||||
common: { label: "经销商", icon: Building, color: "bg-blue-100 text-blue-800" },
|
common: { label: "区域负责人", icon: Building, color: "bg-blue-100 text-blue-800" },
|
||||||
mall: { label: "商场管理员", icon: Store, color: "bg-green-100 text-green-800" },
|
mall: { label: "商场管理员", icon: Store, color: "bg-green-100 text-green-800" },
|
||||||
merchant: { label: "商户", icon: User, color: "bg-yellow-100 text-yellow-800" },
|
merchant: { label: "商户", icon: User, color: "bg-yellow-100 text-yellow-800" },
|
||||||
worker: { label: "维修工人", icon: Wrench, color: "bg-gray-100 text-gray-800" },
|
worker: { label: "维修工人", icon: Wrench, color: "bg-gray-100 text-gray-800" },
|
||||||
@@ -818,7 +818,7 @@ function CreateUserForm({ roles, onClose }: { roles: Role[]; onClose: () => void
|
|||||||
<Label htmlFor="provinces">归属省份</Label>
|
<Label htmlFor="provinces">归属省份</Label>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="text-sm text-gray-500">
|
<div className="text-sm text-gray-500">
|
||||||
{formData.role === "common" ? "经销商可选择多个省份" : "其他角色只能选择一个省份"}
|
{formData.role === "common" ? "区域负责人可选择多个省份" : "其他角色只能选择一个省份"}
|
||||||
</div>
|
</div>
|
||||||
{provincesLoading ? (
|
{provincesLoading ? (
|
||||||
<div className="text-sm text-gray-500">正在加载省份数据...</div>
|
<div className="text-sm text-gray-500">正在加载省份数据...</div>
|
||||||
@@ -1113,7 +1113,7 @@ function EditUserForm({
|
|||||||
<Label htmlFor="edit-provinces">归属省份</Label>
|
<Label htmlFor="edit-provinces">归属省份</Label>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="text-sm text-gray-500">
|
<div className="text-sm text-gray-500">
|
||||||
{formData.role === "common" ? "经销商可选择多个省份" : "其他角色只能选择一个省份"}
|
{formData.role === "common" ? "区域负责人可选择多个省份" : "其他角色只能选择一个省份"}
|
||||||
</div>
|
</div>
|
||||||
{provincesLoading ? (
|
{provincesLoading ? (
|
||||||
<div className="text-sm text-gray-500">正在加载省份数据...</div>
|
<div className="text-sm text-gray-500">正在加载省份数据...</div>
|
||||||
|
|||||||
@@ -1157,7 +1157,7 @@ export default function EquipmentPage() {
|
|||||||
<TableHead className="font-medium">商户信息</TableHead>
|
<TableHead className="font-medium">商户信息</TableHead>
|
||||||
<TableHead className="font-medium text-center">状态</TableHead>
|
<TableHead className="font-medium text-center">状态</TableHead>
|
||||||
<TableHead className="font-medium">检测信息</TableHead>
|
<TableHead className="font-medium">检测信息</TableHead>
|
||||||
<TableHead className="font-medium">负责经销商</TableHead>
|
<TableHead className="font-medium">负责区域负责人</TableHead>
|
||||||
<TableHead className="font-medium text-center">操作</TableHead>
|
<TableHead className="font-medium text-center">操作</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@@ -1341,10 +1341,10 @@ export default function EquipmentPage() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 负责经销商 */}
|
{/* 负责区域负责人 */}
|
||||||
{item.createdBy && (
|
{item.createdBy && (
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<div className="text-xs font-medium text-gray-700">负责经销商</div>
|
<div className="text-xs font-medium text-gray-700">负责区域负责人</div>
|
||||||
<div className="font-medium text-sm text-gray-900 break-words">{item.createdBy}</div>
|
<div className="font-medium text-sm text-gray-900 break-words">{item.createdBy}</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -54,20 +54,20 @@ export default function InventoryPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取经销商数据
|
// 获取区域负责人数据
|
||||||
const fetchDealers = async () => {
|
const fetchDealers = async () => {
|
||||||
try {
|
try {
|
||||||
const roleId = "2"
|
const roleId = "2"
|
||||||
const result = await apiGet<any>(`/back/findNextInfo?roleId=${roleId}`)
|
const result = await apiGet<any>(`/back/findNextInfo?roleId=${roleId}`)
|
||||||
console.log('经销商数据:', result)
|
console.log('区域负责人数据:', result)
|
||||||
|
|
||||||
if (result && result.code === 200 && result.data && Array.isArray(result.data)) {
|
if (result && result.code === 200 && result.data && Array.isArray(result.data)) {
|
||||||
setDealers(result.data)
|
setDealers(result.data)
|
||||||
} else {
|
} else {
|
||||||
console.error('获取经销商失败:', result?.msg || '未知错误')
|
console.error('获取区域负责人失败:', result?.msg || '未知错误')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('请求经销商失败:', error)
|
console.error('请求区域负责人失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ export default function InventoryPage() {
|
|||||||
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
|
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl sm:text-3xl font-bold text-gray-900">库存管理</h1>
|
<h1 className="text-2xl sm:text-3xl font-bold text-gray-900">库存管理</h1>
|
||||||
<p className="text-sm sm:text-base text-gray-600">管理设备配件和耗材库存,总公司发货给经销商</p>
|
<p className="text-sm sm:text-base text-gray-600">管理设备配件和耗材库存,总公司发货给区域负责人</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-2 w-full sm:w-auto">
|
<div className="flex space-x-2 w-full sm:w-auto">
|
||||||
<Dialog open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen}>
|
<Dialog open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen}>
|
||||||
@@ -282,7 +282,7 @@ export default function InventoryPage() {
|
|||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-lg sm:text-xl">库存列表</CardTitle>
|
<CardTitle className="text-lg sm:text-xl">库存列表</CardTitle>
|
||||||
<CardDescription className="text-xs sm:text-sm">查看和管理所有库存物品,支持向经销商发货</CardDescription>
|
<CardDescription className="text-xs sm:text-sm">查看和管理所有库存物品,支持向区域负责人发货</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="flex flex-col sm:flex-row gap-4 mb-6">
|
<div className="flex flex-col sm:flex-row gap-4 mb-6">
|
||||||
@@ -441,7 +441,7 @@ export default function InventoryPage() {
|
|||||||
<DialogContent className="max-w-2xl max-h-[95vh] overflow-y-auto w-[95vw] sm:w-full p-3 sm:p-6">
|
<DialogContent className="max-w-2xl max-h-[95vh] overflow-y-auto w-[95vw] sm:w-full p-3 sm:p-6">
|
||||||
<DialogHeader className="pb-2 sm:pb-4">
|
<DialogHeader className="pb-2 sm:pb-4">
|
||||||
<DialogTitle className="text-base sm:text-lg">出库操作</DialogTitle>
|
<DialogTitle className="text-base sm:text-lg">出库操作</DialogTitle>
|
||||||
<DialogDescription className="text-xs sm:text-sm">向经销商发货</DialogDescription>
|
<DialogDescription className="text-xs sm:text-sm">向区域负责人发货</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<OutboundForm
|
<OutboundForm
|
||||||
item={item}
|
item={item}
|
||||||
@@ -567,7 +567,7 @@ export default function InventoryPage() {
|
|||||||
<DialogContent className="max-w-2xl max-h-[95vh] overflow-y-auto w-[95vw] sm:w-full p-3 sm:p-6">
|
<DialogContent className="max-w-2xl max-h-[95vh] overflow-y-auto w-[95vw] sm:w-full p-3 sm:p-6">
|
||||||
<DialogHeader className="pb-2 sm:pb-4">
|
<DialogHeader className="pb-2 sm:pb-4">
|
||||||
<DialogTitle className="text-base sm:text-lg">出库操作</DialogTitle>
|
<DialogTitle className="text-base sm:text-lg">出库操作</DialogTitle>
|
||||||
<DialogDescription className="text-xs sm:text-sm">向经销商发货</DialogDescription>
|
<DialogDescription className="text-xs sm:text-sm">向区域负责人发货</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<OutboundForm
|
<OutboundForm
|
||||||
item={item}
|
item={item}
|
||||||
@@ -1036,7 +1036,7 @@ function OutboundForm({ item, dealers, onRefreshDealers, onClose, onSuccess }: {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1.5 sm:space-y-2">
|
<div className="space-y-1.5 sm:space-y-2">
|
||||||
<Label className="text-sm sm:text-base">收货经销商</Label>
|
<Label className="text-sm sm:text-base">收货区域负责人</Label>
|
||||||
<Select
|
<Select
|
||||||
value={formData.dealer}
|
value={formData.dealer}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
@@ -1056,7 +1056,7 @@ function OutboundForm({ item, dealers, onRefreshDealers, onClose, onSuccess }: {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder={dealers.length === 0 ? "加载经销商..." : "选择经销商"} />
|
<SelectValue placeholder={dealers.length === 0 ? "加载区域负责人..." : "选择区域负责人"} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{dealers.length === 0 ? (
|
{dealers.length === 0 ? (
|
||||||
@@ -1069,7 +1069,7 @@ function OutboundForm({ item, dealers, onRefreshDealers, onClose, onSuccess }: {
|
|||||||
key={dealer.userId || `dealer-${index}`}
|
key={dealer.userId || `dealer-${index}`}
|
||||||
value={dealer.userName || dealer.nickName || `dealer-${index}`}
|
value={dealer.userName || dealer.nickName || `dealer-${index}`}
|
||||||
>
|
>
|
||||||
{dealer.userName || dealer.nickName || '未知经销商'}
|
{dealer.userName || dealer.nickName || '未知区域负责人'}
|
||||||
{dealer.nickName && dealer.userName !== dealer.nickName ? ` (${dealer.nickName})` : ''}
|
{dealer.nickName && dealer.userName !== dealer.nickName ? ` (${dealer.nickName})` : ''}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -864,7 +864,7 @@ export default function MallsPage() {
|
|||||||
<div className="relative w-full sm:w-auto">
|
<div className="relative w-full sm:w-auto">
|
||||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索商场名称、地址或经销商..."
|
placeholder="搜索商场名称、地址或区域负责人..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
className="pl-8 w-full sm:w-80"
|
className="pl-8 w-full sm:w-80"
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ interface TotalMerchant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function MerchantsPage() {
|
export default function MerchantsPage() {
|
||||||
const [searchTerm, setSearchTerm] = useState("")
|
const [merchantNameSearch, setMerchantNameSearch] = useState("")
|
||||||
|
const [contactPersonSearch, setContactPersonSearch] = useState("")
|
||||||
|
const [contactPhoneSearch, setContactPhoneSearch] = useState("")
|
||||||
const [statusFilter, setStatusFilter] = useState("all")
|
const [statusFilter, setStatusFilter] = useState("all")
|
||||||
const [isAddMerchantOpen, setIsAddMerchantOpen] = useState(false)
|
const [isAddMerchantOpen, setIsAddMerchantOpen] = useState(false)
|
||||||
const [isEditMerchantOpen, setIsEditMerchantOpen] = useState(false)
|
const [isEditMerchantOpen, setIsEditMerchantOpen] = useState(false)
|
||||||
@@ -241,10 +243,38 @@ export default function MerchantsPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取商户列表
|
// 获取商户列表
|
||||||
const fetchMerchants = async (page = currentPage, size = pageSize) => {
|
const fetchMerchants = async (
|
||||||
|
page = currentPage,
|
||||||
|
size = pageSize,
|
||||||
|
merchantName = merchantNameSearch,
|
||||||
|
contactPerson = contactPersonSearch,
|
||||||
|
contactPhone = contactPhoneSearch,
|
||||||
|
equipmentStatus = statusFilter
|
||||||
|
) => {
|
||||||
setLoadingMerchants(true)
|
setLoadingMerchants(true)
|
||||||
try {
|
try {
|
||||||
const response = await apiGet(`/back/merchants/list?pageNum=${page}&pageSize=${size}`)
|
// 构建查询参数
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
pageNum: page.toString(),
|
||||||
|
pageSize: size.toString(),
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加搜索参数(如果有值)
|
||||||
|
if (merchantName.trim()) {
|
||||||
|
params.append('merchantName', merchantName.trim())
|
||||||
|
}
|
||||||
|
if (contactPerson.trim()) {
|
||||||
|
params.append('contactPerson', contactPerson.trim())
|
||||||
|
}
|
||||||
|
if (contactPhone.trim()) {
|
||||||
|
params.append('contactPhone', contactPhone.trim())
|
||||||
|
}
|
||||||
|
// 添加状态筛选参数(如果不是全部)
|
||||||
|
if (equipmentStatus && equipmentStatus !== "all") {
|
||||||
|
params.append('equipmentStatus', equipmentStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await apiGet(`/back/merchants/list?${params.toString()}`)
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
const merchantsData = response.rows || []
|
const merchantsData = response.rows || []
|
||||||
setTotal(parseInt(response.total) || 0)
|
setTotal(parseInt(response.total) || 0)
|
||||||
@@ -276,14 +306,14 @@ export default function MerchantsPage() {
|
|||||||
// 页码变化处理
|
// 页码变化处理
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
setCurrentPage(page)
|
setCurrentPage(page)
|
||||||
fetchMerchants(page, pageSize)
|
fetchMerchants(page, pageSize, merchantNameSearch, contactPersonSearch, contactPhoneSearch, statusFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 每页大小变化处理
|
// 每页大小变化处理
|
||||||
const handlePageSizeChange = (size: number) => {
|
const handlePageSizeChange = (size: number) => {
|
||||||
setPageSize(size)
|
setPageSize(size)
|
||||||
setCurrentPage(1)
|
setCurrentPage(1)
|
||||||
fetchMerchants(1, size)
|
fetchMerchants(1, size, merchantNameSearch, contactPersonSearch, contactPhoneSearch, statusFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组件加载时获取数据
|
// 组件加载时获取数据
|
||||||
@@ -293,6 +323,18 @@ export default function MerchantsPage() {
|
|||||||
fetchUserEquipmentCount()
|
fetchUserEquipmentCount()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
// 搜索条件变化时调用API(使用防抖)
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
// 重置到第一页
|
||||||
|
setCurrentPage(1)
|
||||||
|
fetchMerchants(1, pageSize, merchantNameSearch, contactPersonSearch, contactPhoneSearch, statusFilter)
|
||||||
|
}, 500) // 500ms 防抖
|
||||||
|
|
||||||
|
return () => clearTimeout(timer)
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [merchantNameSearch, contactPersonSearch, contactPhoneSearch, statusFilter])
|
||||||
|
|
||||||
const [newEquipment, setNewEquipment] = useState({
|
const [newEquipment, setNewEquipment] = useState({
|
||||||
name: "",
|
name: "",
|
||||||
type: "",
|
type: "",
|
||||||
@@ -365,7 +407,7 @@ export default function MerchantsPage() {
|
|||||||
setIsAddMerchantOpen(false)
|
setIsAddMerchantOpen(false)
|
||||||
|
|
||||||
// 刷新商户列表
|
// 刷新商户列表
|
||||||
fetchMerchants(currentPage, pageSize)
|
fetchMerchants(currentPage, pageSize, merchantNameSearch, contactPersonSearch, contactPhoneSearch, statusFilter)
|
||||||
} else {
|
} else {
|
||||||
console.error('添加商户失败:', result)
|
console.error('添加商户失败:', result)
|
||||||
alert('添加商户失败:' + (result.msg || '未知错误'))
|
alert('添加商户失败:' + (result.msg || '未知错误'))
|
||||||
@@ -504,7 +546,7 @@ export default function MerchantsPage() {
|
|||||||
console.log('编辑商户成功:', result)
|
console.log('编辑商户成功:', result)
|
||||||
alert('编辑商户成功!')
|
alert('编辑商户成功!')
|
||||||
setIsEditMerchantOpen(false)
|
setIsEditMerchantOpen(false)
|
||||||
fetchMerchants(currentPage, pageSize)
|
fetchMerchants(currentPage, pageSize, merchantNameSearch, contactPersonSearch, contactPhoneSearch)
|
||||||
} else {
|
} else {
|
||||||
console.error('编辑商户失败:', result)
|
console.error('编辑商户失败:', result)
|
||||||
alert('编辑商户失败:' + (result.msg || '未知错误'))
|
alert('编辑商户失败:' + (result.msg || '未知错误'))
|
||||||
@@ -525,23 +567,8 @@ export default function MerchantsPage() {
|
|||||||
fetchMerchantEquipments(merchantId)
|
fetchMerchantEquipments(merchantId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredMerchants = merchants.filter((merchant) => {
|
// 直接使用从后端返回的商户列表(搜索和状态筛选已由后端处理)
|
||||||
const matchesSearch =
|
const filteredMerchants = merchants
|
||||||
merchant.merchantName?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
||||||
merchant.contactPerson?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
||||||
merchant.mallLocation?.toLowerCase().includes(searchTerm.toLowerCase())
|
|
||||||
|
|
||||||
let matchesStatus = true
|
|
||||||
if (statusFilter === "expired") {
|
|
||||||
matchesStatus = merchant.expiredCount > 0
|
|
||||||
} else if (statusFilter === "expiring") {
|
|
||||||
matchesStatus = merchant.expiringCount > 0
|
|
||||||
} else if (statusFilter === "normal") {
|
|
||||||
matchesStatus = merchant.expiredCount === 0 && merchant.expiringCount === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchesSearch && matchesStatus
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4 sm:space-y-6 p-4 sm:p-6">
|
<div className="space-y-4 sm:space-y-6 p-4 sm:p-6">
|
||||||
@@ -565,18 +592,37 @@ export default function MerchantsPage() {
|
|||||||
<CardDescription>查看和管理所有商户信息及设备状态 - 共 {total} 条记录,当前第 {currentPage} 页</CardDescription>
|
<CardDescription>查看和管理所有商户信息及设备状态 - 共 {total} 条记录,当前第 {currentPage} 页</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="flex flex-col sm:flex-row gap-4 mb-6">
|
<div className="flex flex-col gap-4 mb-6">
|
||||||
<div className="flex-1">
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索商户名称、联系人或商场..."
|
placeholder="搜索商户名称..."
|
||||||
value={searchTerm}
|
value={merchantNameSearch}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setMerchantNameSearch(e.target.value)}
|
||||||
|
className="pl-10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative">
|
||||||
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
||||||
|
<Input
|
||||||
|
placeholder="搜索联系人..."
|
||||||
|
value={contactPersonSearch}
|
||||||
|
onChange={(e) => setContactPersonSearch(e.target.value)}
|
||||||
|
className="pl-10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative">
|
||||||
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
||||||
|
<Input
|
||||||
|
placeholder="搜索联系电话..."
|
||||||
|
value={contactPhoneSearch}
|
||||||
|
onChange={(e) => setContactPhoneSearch(e.target.value)}
|
||||||
className="pl-10"
|
className="pl-10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
|
|
||||||
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
||||||
<SelectTrigger className="w-full sm:w-48">
|
<SelectTrigger className="w-full sm:w-48">
|
||||||
@@ -604,6 +650,7 @@ export default function MerchantsPage() {
|
|||||||
导出
|
导出
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Desktop Table View */}
|
{/* Desktop Table View */}
|
||||||
<div className="hidden md:block rounded-md border overflow-x-auto">
|
<div className="hidden md:block rounded-md border overflow-x-auto">
|
||||||
@@ -614,7 +661,7 @@ export default function MerchantsPage() {
|
|||||||
<TableHead>商户名称</TableHead>
|
<TableHead>商户名称</TableHead>
|
||||||
<TableHead>联系人</TableHead>
|
<TableHead>联系人</TableHead>
|
||||||
<TableHead>所属商场</TableHead>
|
<TableHead>所属商场</TableHead>
|
||||||
<TableHead>经销商</TableHead>
|
<TableHead>区域负责人</TableHead>
|
||||||
<TableHead>地址</TableHead>
|
<TableHead>地址</TableHead>
|
||||||
<TableHead>设备数量</TableHead>
|
<TableHead>设备数量</TableHead>
|
||||||
<TableHead>状态</TableHead>
|
<TableHead>状态</TableHead>
|
||||||
@@ -747,7 +794,7 @@ export default function MerchantsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div className="text-xs text-gray-500 mb-1">经销商</div>
|
<div className="text-xs text-gray-500 mb-1">区域负责人</div>
|
||||||
<div className="text-sm">{merchant.dealerName || "无"}</div>
|
<div className="text-sm">{merchant.dealerName || "无"}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ interface StatisticsData {
|
|||||||
totalMerchants: number
|
totalMerchants: number
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义经销商分布数据接口
|
// 定义区域负责人分布数据接口
|
||||||
interface DealerDistribution {
|
interface DealerDistribution {
|
||||||
equipmentCount: number
|
equipmentCount: number
|
||||||
dealerName: string
|
dealerName: string
|
||||||
@@ -110,7 +110,7 @@ export default function StatisticsPage() {
|
|||||||
setDealerDistributionData(response.data.distributionList)
|
setDealerDistributionData(response.data.distributionList)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取经销商分布数据失败:', error)
|
console.error('获取区域负责人分布数据失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,9 +379,9 @@ export default function StatisticsPage() {
|
|||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center space-x-2">
|
<CardTitle className="flex items-center space-x-2">
|
||||||
<MapPin className="h-5 w-5" />
|
<MapPin className="h-5 w-5" />
|
||||||
<span>全国经销商分布</span>
|
<span>全国区域负责人分布</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>各省份经销商及业务数据概览</CardDescription>
|
<CardDescription>各省份区域负责人及业务数据概览</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
|
|||||||
@@ -861,7 +861,7 @@ function CreateWorkOrderForm({ onClose }: { onClose: () => void }) {
|
|||||||
const workerNames = selectedWorkers.map(w => w.name).join(",")
|
const workerNames = selectedWorkers.map(w => w.name).join(",")
|
||||||
// 拼接工人电话(使用逗号分隔)
|
// 拼接工人电话(使用逗号分隔)
|
||||||
const workerPhones = selectedWorkers.map(w => w.phone).join(",")
|
const workerPhones = selectedWorkers.map(w => w.phone).join(",")
|
||||||
// 使用第一个工人的经销商ID
|
// 使用第一个工人的区域负责人ID
|
||||||
const distributorUserId = selectedWorkers[0].distributorUserId || ""
|
const distributorUserId = selectedWorkers[0].distributorUserId || ""
|
||||||
|
|
||||||
// 生成工单编号
|
// 生成工单编号
|
||||||
@@ -1259,7 +1259,7 @@ function EditWorkOrderForm({ workOrder, onClose }: { workOrder: WorkOrder; onClo
|
|||||||
const workerNames = selectedWorkers.map(w => w.name).join(",")
|
const workerNames = selectedWorkers.map(w => w.name).join(",")
|
||||||
// 拼接工人电话(使用逗号分隔)
|
// 拼接工人电话(使用逗号分隔)
|
||||||
const workerPhones = selectedWorkers.map(w => w.phone).join(",")
|
const workerPhones = selectedWorkers.map(w => w.phone).join(",")
|
||||||
// 使用第一个工人的经销商ID
|
// 使用第一个工人的区域负责人ID
|
||||||
const distributorUserId = selectedWorkers[0].distributorUserId || ""
|
const distributorUserId = selectedWorkers[0].distributorUserId || ""
|
||||||
|
|
||||||
// 构建API请求数据
|
// 构建API请求数据
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export default function WorkersPage() {
|
|||||||
workerId: worker.jobNum || worker.workersId || `W${worker.id}`,
|
workerId: worker.jobNum || worker.workersId || `W${worker.id}`,
|
||||||
phone: worker.phone,
|
phone: worker.phone,
|
||||||
dealerId: worker.distributorUserId,
|
dealerId: worker.distributorUserId,
|
||||||
dealerName: worker.distributorUser || '未知经销商',
|
dealerName: worker.distributorUser || '未知区域负责人',
|
||||||
province: worker.province,
|
province: worker.province,
|
||||||
skillLevel: mapAPISkillLevelToDisplay(worker.skillLevel),
|
skillLevel: mapAPISkillLevelToDisplay(worker.skillLevel),
|
||||||
joinDate: worker.createdAt,
|
joinDate: worker.createdAt,
|
||||||
@@ -217,7 +217,7 @@ export default function WorkersPage() {
|
|||||||
loadProvinces()
|
loadProvinces()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// 加载经销商数据
|
// 加载区域负责人数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadDealers = async () => {
|
const loadDealers = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -225,7 +225,7 @@ export default function WorkersPage() {
|
|||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
setDealers(response.data)
|
setDealers(response.data)
|
||||||
} else {
|
} else {
|
||||||
console.error('获取经销商数据失败:', response.msg)
|
console.error('获取区域负责人数据失败:', response.msg)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading dealers:', err)
|
console.error('Error loading dealers:', err)
|
||||||
@@ -614,13 +614,13 @@ export default function WorkersPage() {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-1.5 sm:gap-2">
|
<div className="grid gap-1.5 sm:gap-2">
|
||||||
<Label htmlFor="dealer" className="text-sm sm:text-base">所属经销商</Label>
|
<Label htmlFor="dealer" className="text-sm sm:text-base">所属区域负责人</Label>
|
||||||
<Select
|
<Select
|
||||||
value={newWorker.dealerId}
|
value={newWorker.dealerId}
|
||||||
onValueChange={(value) => setNewWorker({ ...newWorker, dealerId: value })}
|
onValueChange={(value) => setNewWorker({ ...newWorker, dealerId: value })}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="选择经销商" />
|
<SelectValue placeholder="选择区域负责人" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="max-h-[300px]">
|
<SelectContent className="max-h-[300px]">
|
||||||
{dealers.map((dealer) => (
|
{dealers.map((dealer) => (
|
||||||
@@ -701,13 +701,13 @@ export default function WorkersPage() {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-1.5 sm:gap-2">
|
<div className="grid gap-1.5 sm:gap-2">
|
||||||
<Label htmlFor="edit-dealer" className="text-sm sm:text-base">所属经销商</Label>
|
<Label htmlFor="edit-dealer" className="text-sm sm:text-base">所属区域负责人</Label>
|
||||||
<Select
|
<Select
|
||||||
value={editWorker.dealerId}
|
value={editWorker.dealerId}
|
||||||
onValueChange={(value) => setEditWorker({ ...editWorker, dealerId: value })}
|
onValueChange={(value) => setEditWorker({ ...editWorker, dealerId: value })}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="选择经销商" />
|
<SelectValue placeholder="选择区域负责人" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="max-h-[300px]">
|
<SelectContent className="max-h-[300px]">
|
||||||
{dealers.map((dealer) => (
|
{dealers.map((dealer) => (
|
||||||
@@ -771,7 +771,7 @@ export default function WorkersPage() {
|
|||||||
<span className="text-sm font-medium">{deletingWorker.phone}</span>
|
<span className="text-sm font-medium">{deletingWorker.phone}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<span className="text-sm text-gray-600">经销商:</span>
|
<span className="text-sm text-gray-600">区域负责人:</span>
|
||||||
<span className="text-sm font-medium">{deletingWorker.dealerName}</span>
|
<span className="text-sm font-medium">{deletingWorker.dealerName}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -811,7 +811,7 @@ export default function WorkersPage() {
|
|||||||
<div className="relative flex-1 sm:flex-initial">
|
<div className="relative flex-1 sm:flex-initial">
|
||||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索工人姓名、工号或经销商..."
|
placeholder="搜索工人姓名、工号或区域负责人..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
className="pl-8 w-full sm:w-80"
|
className="pl-8 w-full sm:w-80"
|
||||||
|
|||||||
Reference in New Issue
Block a user