From 0d32f2d1872491ef5dfb55fa42d058a5e1163302 Mon Sep 17 00:00:00 2001 From: menxipeng Date: Tue, 21 Oct 2025 23:23:46 +0800 Subject: [PATCH] q q q --- src/components/pages/EquipmentPage.tsx | 2 +- .../pages/ValueAddedServicesPage.tsx | 592 ++++++++++++------ src/lib/services/service.ts | 49 ++ src/lib/services/user.ts | 12 + src/lib/types/service.ts | 45 ++ src/lib/types/user.ts | 44 ++ 6 files changed, 561 insertions(+), 183 deletions(-) create mode 100644 src/lib/services/service.ts create mode 100644 src/lib/services/user.ts create mode 100644 src/lib/types/service.ts create mode 100644 src/lib/types/user.ts diff --git a/src/components/pages/EquipmentPage.tsx b/src/components/pages/EquipmentPage.tsx index e6b3d0a..31ab858 100644 --- a/src/components/pages/EquipmentPage.tsx +++ b/src/components/pages/EquipmentPage.tsx @@ -745,7 +745,7 @@ export default function EquipmentPage() {
- {item.equipmentId} + {item.equId}
{item.equipmentName}
类型: {equipmentTypeDisplay}
diff --git a/src/components/pages/ValueAddedServicesPage.tsx b/src/components/pages/ValueAddedServicesPage.tsx index e58a829..f47910a 100644 --- a/src/components/pages/ValueAddedServicesPage.tsx +++ b/src/components/pages/ValueAddedServicesPage.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react" +import { useState, useEffect } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card" import { Button } from "../ui/button" import { Input } from "../ui/input" @@ -16,121 +16,165 @@ import { DialogTrigger, } from "../ui/dialog" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../ui/table" -import { Plus, Edit, Trash2, Phone } from "lucide-react" - -interface ValueAddedService { - id: string - title: string - description: string - status: "active" | "inactive" - assignedDealers: string[] - createdAt: string - updatedAt: string -} - -interface Dealer { - id: string - name: string - phone: string - region: string -} +import { Plus, Edit, Trash2, Phone, ChevronLeft, ChevronRight } from "lucide-react" +import { getServiceList, createService, updateService, deleteService } from "@/lib/services/service" +import { ValueAddedService } from "@/lib/types/service" +import { getUserByRoleKey } from "@/lib/services/user" +import type { User } from "@/lib/types/user" export default function ValueAddedServicesPage() { - const [services, setServices] = useState([ - { - id: "1", - title: "消防设备年检服务", - description: "提供专业的消防设备年度检测服务,确保设备符合安全标准", - status: "active", - assignedDealers: ["dealer1", "dealer2"], - createdAt: "2024-01-15", - updatedAt: "2024-01-15", - }, - { - id: "2", - title: "紧急维修服务", - description: "24小时紧急维修服务,快速响应设备故障", - status: "active", - assignedDealers: ["dealer1", "dealer3"], - createdAt: "2024-01-10", - updatedAt: "2024-01-20", - }, - ]) - - const [dealers] = useState([ - { id: "dealer1", name: "华东经销商", phone: "138****1234", region: "华东区" }, - { id: "dealer2", name: "华南经销商", phone: "139****5678", region: "华南区" }, - { id: "dealer3", name: "华北经销商", phone: "137****9012", region: "华北区" }, - ]) - + const [services, setServices] = useState([]) + const [adminUsers, setAdminUsers] = useState([]) + const [commonUsers, setCommonUsers] = useState([]) const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false) const [isEditDialogOpen, setIsEditDialogOpen] = useState(false) const [selectedService, setSelectedService] = useState(null) + const [loading, setLoading] = useState(false) + const [pageNum, setPageNum] = useState(1) + const [pageSize, setPageSize] = useState(10) + const [total, setTotal] = useState(0) + const [formData, setFormData] = useState({ - title: "", + serviceTitle: "", description: "", - status: "active" as "active" | "inactive", - assignedDealers: [] as string[], + status: "1", + assignedAdmin: "", + assignedCommon: "", }) - const handleCreateService = () => { - const newService: ValueAddedService = { - id: Date.now().toString(), - title: formData.title, - description: formData.description, - status: formData.status, - assignedDealers: formData.assignedDealers, - createdAt: new Date().toISOString().split("T")[0], - updatedAt: new Date().toISOString().split("T")[0], + useEffect(() => { + loadServices() + loadUsers() + }, [pageNum, pageSize]) + + const loadServices = async () => { + setLoading(true) + try { + const response = await getServiceList({ pageNum, pageSize }) + if (response.code === 200) { + setServices(response.rows) + setTotal(response.total) + } + } catch (error) { + console.error("加载服务列表失败:", error) + } finally { + setLoading(false) } - setServices([...services, newService]) + } + + const loadUsers = async () => { + try { + const [adminResponse, commonResponse] = await Promise.all([ + getUserByRoleKey("admin"), + getUserByRoleKey("common"), + ]) + + if (adminResponse.code === 200 && adminResponse.data) { + setAdminUsers(adminResponse.data) + } + + if (commonResponse.code === 200 && commonResponse.data) { + setCommonUsers(commonResponse.data) + } + } catch (error) { + console.error("加载用户列表失败:", error) + } + } + + const handleCreateService = async () => { + setLoading(true) + try { + const response = await createService(formData) + if (response.code === 200) { setIsCreateDialogOpen(false) resetForm() + loadServices() + } else { + alert(response.msg || "创建失败") + } + } catch (error) { + console.error("创建服务失败:", error) + alert("创建服务失败") + } finally { + setLoading(false) + } } - const handleEditService = () => { + const handleEditService = async () => { if (!selectedService) return - const updatedServices = services.map((service) => - service.id === selectedService.id - ? { - ...service, - title: formData.title, - description: formData.description, - status: formData.status, - assignedDealers: formData.assignedDealers, - updatedAt: new Date().toISOString().split("T")[0], - } - : service, - ) - setServices(updatedServices) + setLoading(true) + try { + const response = await updateService({ + id: selectedService.id, + ...formData, + }) + if (response.code === 200) { setIsEditDialogOpen(false) resetForm() + loadServices() + } else { + alert(response.msg || "更新失败") + } + } catch (error) { + console.error("更新服务失败:", error) + alert("更新服务失败") + } finally { + setLoading(false) + } } - const handleDeleteService = (id: string) => { - setServices(services.filter((service) => service.id !== id)) + const handleDeleteService = async (id: string) => { + if (!confirm("确定要删除该服务吗?")) return + + setLoading(true) + try { + const response = await deleteService(id) + if (response.code === 200) { + loadServices() + } else { + alert(response.msg || "删除失败") + } + } catch (error) { + console.error("删除服务失败:", error) + alert("删除服务失败") + } finally { + setLoading(false) + } } - const toggleServiceStatus = (id: string) => { - const updatedServices = services.map((service) => - service.id === id - ? { - ...service, - status: service.status === "active" ? ("inactive" as const) : ("active" as const), - updatedAt: new Date().toISOString().split("T")[0], - } - : service, - ) - setServices(updatedServices) + const toggleServiceStatus = async (service: ValueAddedService) => { + setLoading(true) + try { + const newStatus = service.status === "1" ? "0" : "1" + const response = await updateService({ + id: service.id, + serviceTitle: service.serviceTitle, + description: service.description, + status: newStatus, + assignedAdmin: service.assignedAdmin || "", + assignedCommon: service.assignedCommon || "", + }) + if (response.code === 200) { + loadServices() + } else { + alert(response.msg || "更新状态失败") + } + } catch (error) { + console.error("更新状态失败:", error) + alert("更新状态失败") + } finally { + setLoading(false) + } } const resetForm = () => { setFormData({ - title: "", + serviceTitle: "", description: "", - status: "active", - assignedDealers: [], + status: "1", + assignedAdmin: "", + assignedCommon: "", }) setSelectedService(null) } @@ -138,16 +182,37 @@ export default function ValueAddedServicesPage() { const openEditDialog = (service: ValueAddedService) => { setSelectedService(service) setFormData({ - title: service.title, + serviceTitle: service.serviceTitle, description: service.description, status: service.status, - assignedDealers: service.assignedDealers, + assignedAdmin: service.assignedAdmin || "", + assignedCommon: service.assignedCommon || "", }) setIsEditDialogOpen(true) } - const getDealerName = (dealerId: string) => { - return dealers.find((dealer) => dealer.id === dealerId)?.name || "未知经销商" + const getUserName = (userId: string, userList: User[]) => { + const user = userList.find((u) => u.userId === userId) + return user ? (user.nickName || user.userName) : "未知用户" + } + + const getUsersByIds = (ids: string) => { + if (!ids) return [] + return ids.split(",").filter(Boolean) + } + + const totalPages = Math.ceil(total / pageSize) + + const handlePrevPage = () => { + if (pageNum > 1) { + setPageNum(pageNum - 1) + } + } + + const handleNextPage = () => { + if (pageNum < totalPages) { + setPageNum(pageNum + 1) + } } return ( @@ -175,8 +240,8 @@ export default function ValueAddedServicesPage() { setFormData({ ...formData, title: e.target.value })} + value={formData.serviceTitle} + onChange={(e) => setFormData({ ...formData, serviceTitle: e.target.value })} placeholder="请输入服务标题" />
@@ -190,49 +255,96 @@ export default function ValueAddedServicesPage() { rows={3} /> +
+ +
+ {adminUsers.map((user) => { + const assignedIds = formData.assignedAdmin.split(",").filter(Boolean) + const userId = user.userId + return ( +
+ { + const ids = formData.assignedAdmin.split(",").filter(Boolean) + if (e.target.checked) { + setFormData({ + ...formData, + assignedAdmin: [...ids, userId].join(","), + }) + } else { + setFormData({ + ...formData, + assignedAdmin: ids.filter((id) => id !== userId).join(","), + }) + } + }} + /> + +
+ ) + })} +
+
-
- {dealers.map((dealer) => ( -
- { - if (e.target.checked) { - setFormData({ - ...formData, - assignedDealers: [...formData.assignedDealers, dealer.id], - }) - } else { - setFormData({ - ...formData, - assignedDealers: formData.assignedDealers.filter((id) => id !== dealer.id), - }) - } - }} - /> -
- - + @@ -251,56 +363,125 @@ export default function ValueAddedServicesPage() { 服务标题 描述 状态 - 分配经销商 + 总公司 + 经销商 创建时间 操作 - {services.map((service) => ( + {loading ? ( + + + 加载中... + + + ) : services.length === 0 ? ( + + + 暂无数据 + + + ) : ( + services.map((service) => ( - {service.title} + {service.serviceTitle} {service.description}
toggleServiceStatus(service.id)} + checked={service.status === "1"} + onCheckedChange={() => toggleServiceStatus(service)} + disabled={loading} /> - - {service.status === "active" ? "上架" : "下架"} + + {service.status === "1" ? "上架" : "下架"}
- -
- {service.assignedDealers.slice(0, 2).map((dealerId) => ( - - {getDealerName(dealerId)} - - ))} - {service.assignedDealers.length > 2 && ( - - +{service.assignedDealers.length - 2} - - )} -
-
- {service.createdAt} + +
+ {getUsersByIds(service.assignedAdmin || "").length > 0 ? ( + <> + {getUsersByIds(service.assignedAdmin).slice(0, 2).map((userId) => ( + + {getUserName(userId, adminUsers)} + + ))} + {getUsersByIds(service.assignedAdmin).length > 2 && ( + + +{getUsersByIds(service.assignedAdmin).length - 2} + + )} + + ) : ( + - + )} +
+
+ +
+ {getUsersByIds(service.assignedCommon || "").length > 0 ? ( + <> + {getUsersByIds(service.assignedCommon).slice(0, 2).map((userId) => ( + + {getUserName(userId, commonUsers)} + + ))} + {getUsersByIds(service.assignedCommon).length > 2 && ( + + +{getUsersByIds(service.assignedCommon).length - 2} + + )} + + ) : ( + - + )} +
+
+ {service.createdTime || "-"}
- -
- ))} + )) + )}
+ + {/* Pagination */} +
+
+ 共 {total} 条记录,第 {pageNum} / {totalPages || 1} 页 +
+
+ + +
+
@@ -316,8 +497,8 @@ export default function ValueAddedServicesPage() { setFormData({ ...formData, title: e.target.value })} + value={formData.serviceTitle} + onChange={(e) => setFormData({ ...formData, serviceTitle: e.target.value })} placeholder="请输入服务标题" />
@@ -331,49 +512,96 @@ export default function ValueAddedServicesPage() { rows={3} /> +
+ +
+ {adminUsers.map((user) => { + const assignedIds = formData.assignedAdmin.split(",").filter(Boolean) + const userId = user.userId + return ( +
+ { + const ids = formData.assignedAdmin.split(",").filter(Boolean) + if (e.target.checked) { + setFormData({ + ...formData, + assignedAdmin: [...ids, userId].join(","), + }) + } else { + setFormData({ + ...formData, + assignedAdmin: ids.filter((id) => id !== userId).join(","), + }) + } + }} + /> + +
+ ) + })} +
+
-
- {dealers.map((dealer) => ( -
- { - if (e.target.checked) { - setFormData({ - ...formData, - assignedDealers: [...formData.assignedDealers, dealer.id], - }) - } else { - setFormData({ - ...formData, - assignedDealers: formData.assignedDealers.filter((id) => id !== dealer.id), - }) - } - }} - /> -
- - + diff --git a/src/lib/services/service.ts b/src/lib/services/service.ts new file mode 100644 index 0000000..6af99d4 --- /dev/null +++ b/src/lib/services/service.ts @@ -0,0 +1,49 @@ +import { + ServiceListParams, + ServiceListResponse, + ServiceCreateParams, + ServiceUpdateParams, + ServiceResponse +} from '@/lib/types/service' +import { apiGet, apiPost, apiPut, apiDelete } from './api' + +export async function getServiceList(params: ServiceListParams): Promise { + try { + const queryParams = new URLSearchParams({ + pageSize: params.pageSize.toString(), + pageNum: params.pageNum.toString(), + }) + return await apiGet(`/back/services/list?${queryParams}`) + } catch (error) { + console.error('Failed to fetch services:', error) + throw error + } +} + +export async function createService(data: ServiceCreateParams): Promise { + try { + return await apiPost('/back/services/', data) + } catch (error) { + console.error('Failed to create service:', error) + throw error + } +} + +export async function updateService(data: ServiceUpdateParams): Promise { + try { + return await apiPut('/back/services/', data) + } catch (error) { + console.error('Failed to update service:', error) + throw error + } +} + +export async function deleteService(id: string): Promise { + try { + return await apiDelete(`/back/services/${id}`) + } catch (error) { + console.error('Failed to delete service:', error) + throw error + } +} + diff --git a/src/lib/services/user.ts b/src/lib/services/user.ts new file mode 100644 index 0000000..b7999cf --- /dev/null +++ b/src/lib/services/user.ts @@ -0,0 +1,12 @@ +import { UserByRoleResponse } from '@/lib/types/user' +import { apiGet } from './api' + +export async function getUserByRoleKey(roleKey: string): Promise { + try { + return await apiGet(`/back/user/getUserByRoleKey?roleKey=${roleKey}`) + } catch (error) { + console.error(`Failed to fetch users with role ${roleKey}:`, error) + throw error + } +} + diff --git a/src/lib/types/service.ts b/src/lib/types/service.ts new file mode 100644 index 0000000..ec239e9 --- /dev/null +++ b/src/lib/types/service.ts @@ -0,0 +1,45 @@ +export interface ValueAddedService { + id: string + serviceTitle: string + description: string + status: string + assignedAdmin: string + assignedCommon: string + createTime?: string + updateTime?: string +} + +export interface ServiceListParams { + pageSize: number + pageNum: number +} + +export interface ServiceListResponse { + code: number + msg: string + rows: ValueAddedService[] + total: number +} + +export interface ServiceCreateParams { + serviceTitle: string + description: string + status: string + assignedAdmin: string + assignedCommon: string +} + +export interface ServiceUpdateParams { + id: string + serviceTitle: string + description: string + status: string + assignedAdmin: string + assignedCommon: string +} + +export interface ServiceResponse { + code: number + msg: string + data?: any +} diff --git a/src/lib/types/user.ts b/src/lib/types/user.ts new file mode 100644 index 0000000..a52f3e7 --- /dev/null +++ b/src/lib/types/user.ts @@ -0,0 +1,44 @@ +export interface User { + createBy: string + createTime: string + updateBy: string | null + updateTime: string | null + remark: string | null + userId: string + deptId: string | null + userName: string + nickName: string + email: string + phonenumber: string + sex: string + avatar: string + password: string + status: string + delFlag: string + loginIp: string + loginDate: string + pwdUpdateDate: string | null + dept: any + roles: any[] + roleIds: any + postIds: any + roleId: string | null + roleName: string | null + provinceCode: string + parentId: string | null + type: string | null + mallId: string | null + businessLicense: string | null + businessType: string | null + address: string | null + provinceAddress: string | null + shopAddress: string | null + admin: boolean +} + +export interface UserByRoleResponse { + msg: string + code: number + data: User[] +} +