This commit is contained in:
menxipeng
2025-10-21 23:23:46 +08:00
parent e77d28abf7
commit 0d32f2d187
6 changed files with 561 additions and 183 deletions

View File

@@ -745,7 +745,7 @@ export default function EquipmentPage() {
<div className="space-y-1"> <div className="space-y-1">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Shield className="h-4 w-4 text-blue-600" /> <Shield className="h-4 w-4 text-blue-600" />
<span className="font-medium text-blue-600">{item.equipmentId}</span> <span className="font-medium text-blue-600">{item.equId}</span>
</div> </div>
<div className="text-sm font-medium">{item.equipmentName}</div> <div className="text-sm font-medium">{item.equipmentName}</div>
<div className="text-xs text-gray-500">: {equipmentTypeDisplay}</div> <div className="text-xs text-gray-500">: {equipmentTypeDisplay}</div>

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react" import { useState, useEffect } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card"
import { Button } from "../ui/button" import { Button } from "../ui/button"
import { Input } from "../ui/input" import { Input } from "../ui/input"
@@ -16,121 +16,165 @@ import {
DialogTrigger, DialogTrigger,
} from "../ui/dialog" } from "../ui/dialog"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../ui/table" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../ui/table"
import { Plus, Edit, Trash2, Phone } from "lucide-react" import { Plus, Edit, Trash2, Phone, ChevronLeft, ChevronRight } from "lucide-react"
import { getServiceList, createService, updateService, deleteService } from "@/lib/services/service"
interface ValueAddedService { import { ValueAddedService } from "@/lib/types/service"
id: string import { getUserByRoleKey } from "@/lib/services/user"
title: string import type { User } from "@/lib/types/user"
description: string
status: "active" | "inactive"
assignedDealers: string[]
createdAt: string
updatedAt: string
}
interface Dealer {
id: string
name: string
phone: string
region: string
}
export default function ValueAddedServicesPage() { export default function ValueAddedServicesPage() {
const [services, setServices] = useState<ValueAddedService[]>([ const [services, setServices] = useState<ValueAddedService[]>([])
{ const [adminUsers, setAdminUsers] = useState<User[]>([])
id: "1", const [commonUsers, setCommonUsers] = useState<User[]>([])
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<Dealer[]>([
{ id: "dealer1", name: "华东经销商", phone: "138****1234", region: "华东区" },
{ id: "dealer2", name: "华南经销商", phone: "139****5678", region: "华南区" },
{ id: "dealer3", name: "华北经销商", phone: "137****9012", region: "华北区" },
])
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false) const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false)
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false) const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)
const [selectedService, setSelectedService] = useState<ValueAddedService | null>(null) const [selectedService, setSelectedService] = useState<ValueAddedService | null>(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({ const [formData, setFormData] = useState({
title: "", serviceTitle: "",
description: "", description: "",
status: "active" as "active" | "inactive", status: "1",
assignedDealers: [] as string[], assignedAdmin: "",
assignedCommon: "",
}) })
const handleCreateService = () => { useEffect(() => {
const newService: ValueAddedService = { loadServices()
id: Date.now().toString(), loadUsers()
title: formData.title, }, [pageNum, pageSize])
description: formData.description,
status: formData.status, const loadServices = async () => {
assignedDealers: formData.assignedDealers, setLoading(true)
createdAt: new Date().toISOString().split("T")[0], try {
updatedAt: new Date().toISOString().split("T")[0], 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) setIsCreateDialogOpen(false)
resetForm() resetForm()
loadServices()
} else {
alert(response.msg || "创建失败")
}
} catch (error) {
console.error("创建服务失败:", error)
alert("创建服务失败")
} finally {
setLoading(false)
}
} }
const handleEditService = () => { const handleEditService = async () => {
if (!selectedService) return if (!selectedService) return
const updatedServices = services.map((service) => setLoading(true)
service.id === selectedService.id try {
? { const response = await updateService({
...service, id: selectedService.id,
title: formData.title, ...formData,
description: formData.description, })
status: formData.status, if (response.code === 200) {
assignedDealers: formData.assignedDealers,
updatedAt: new Date().toISOString().split("T")[0],
}
: service,
)
setServices(updatedServices)
setIsEditDialogOpen(false) setIsEditDialogOpen(false)
resetForm() resetForm()
loadServices()
} else {
alert(response.msg || "更新失败")
}
} catch (error) {
console.error("更新服务失败:", error)
alert("更新服务失败")
} finally {
setLoading(false)
}
} }
const handleDeleteService = (id: string) => { const handleDeleteService = async (id: string) => {
setServices(services.filter((service) => service.id !== id)) 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 toggleServiceStatus = async (service: ValueAddedService) => {
const updatedServices = services.map((service) => setLoading(true)
service.id === id try {
? { const newStatus = service.status === "1" ? "0" : "1"
...service, const response = await updateService({
status: service.status === "active" ? ("inactive" as const) : ("active" as const), id: service.id,
updatedAt: new Date().toISOString().split("T")[0], serviceTitle: service.serviceTitle,
} description: service.description,
: service, status: newStatus,
) assignedAdmin: service.assignedAdmin || "",
setServices(updatedServices) assignedCommon: service.assignedCommon || "",
})
if (response.code === 200) {
loadServices()
} else {
alert(response.msg || "更新状态失败")
}
} catch (error) {
console.error("更新状态失败:", error)
alert("更新状态失败")
} finally {
setLoading(false)
}
} }
const resetForm = () => { const resetForm = () => {
setFormData({ setFormData({
title: "", serviceTitle: "",
description: "", description: "",
status: "active", status: "1",
assignedDealers: [], assignedAdmin: "",
assignedCommon: "",
}) })
setSelectedService(null) setSelectedService(null)
} }
@@ -138,16 +182,37 @@ export default function ValueAddedServicesPage() {
const openEditDialog = (service: ValueAddedService) => { const openEditDialog = (service: ValueAddedService) => {
setSelectedService(service) setSelectedService(service)
setFormData({ setFormData({
title: service.title, serviceTitle: service.serviceTitle,
description: service.description, description: service.description,
status: service.status, status: service.status,
assignedDealers: service.assignedDealers, assignedAdmin: service.assignedAdmin || "",
assignedCommon: service.assignedCommon || "",
}) })
setIsEditDialogOpen(true) setIsEditDialogOpen(true)
} }
const getDealerName = (dealerId: string) => { const getUserName = (userId: string, userList: User[]) => {
return dealers.find((dealer) => dealer.id === dealerId)?.name || "未知经销商" 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 ( return (
@@ -175,8 +240,8 @@ export default function ValueAddedServicesPage() {
<Label htmlFor="title"></Label> <Label htmlFor="title"></Label>
<Input <Input
id="title" id="title"
value={formData.title} value={formData.serviceTitle}
onChange={(e) => setFormData({ ...formData, title: e.target.value })} onChange={(e) => setFormData({ ...formData, serviceTitle: e.target.value })}
placeholder="请输入服务标题" placeholder="请输入服务标题"
/> />
</div> </div>
@@ -190,49 +255,96 @@ export default function ValueAddedServicesPage() {
rows={3} rows={3}
/> />
</div> </div>
<div>
<Label></Label>
<div className="grid grid-cols-1 gap-2 mt-2 max-h-48 overflow-y-auto border rounded p-2">
{adminUsers.map((user) => {
const assignedIds = formData.assignedAdmin.split(",").filter(Boolean)
const userId = user.userId
return (
<div key={userId} className="flex items-center space-x-2 p-2 border rounded">
<input
type="checkbox"
id={`admin-${userId}`}
checked={assignedIds.includes(userId)}
onChange={(e) => {
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(","),
})
}
}}
/>
<label htmlFor={`admin-${userId}`} className="flex-1 cursor-pointer">
<div className="flex justify-between">
<span className="font-medium">{user.nickName || user.userName}</span>
<span className="text-sm text-gray-500 flex items-center">
<Phone className="h-3 w-3 mr-1" />
{user.phonenumber}
</span>
</div>
</label>
</div>
)
})}
</div>
</div>
<div> <div>
<Label></Label> <Label></Label>
<div className="grid grid-cols-1 gap-2 mt-2"> <div className="grid grid-cols-1 gap-2 mt-2 max-h-48 overflow-y-auto border rounded p-2">
{dealers.map((dealer) => ( {commonUsers.map((user) => {
<div key={dealer.id} className="flex items-center space-x-2 p-2 border rounded"> const assignedIds = formData.assignedCommon.split(",").filter(Boolean)
<input const userId = user.userId
type="checkbox" return (
id={dealer.id} <div key={userId} className="flex items-center space-x-2 p-2 border rounded">
checked={formData.assignedDealers.includes(dealer.id)} <input
onChange={(e) => { type="checkbox"
if (e.target.checked) { id={`common-${userId}`}
setFormData({ checked={assignedIds.includes(userId)}
...formData, onChange={(e) => {
assignedDealers: [...formData.assignedDealers, dealer.id], const ids = formData.assignedCommon.split(",").filter(Boolean)
}) if (e.target.checked) {
} else { setFormData({
setFormData({ ...formData,
...formData, assignedCommon: [...ids, userId].join(","),
assignedDealers: formData.assignedDealers.filter((id) => id !== dealer.id), })
}) } else {
} setFormData({
}} ...formData,
/> assignedCommon: ids.filter((id) => id !== userId).join(","),
<label htmlFor={dealer.id} className="flex-1 cursor-pointer"> })
}
}}
/>
<label htmlFor={`common-${userId}`} className="flex-1 cursor-pointer">
<div className="flex justify-between"> <div className="flex justify-between">
<span className="font-medium">{dealer.name}</span> <span className="font-medium">{user.nickName || user.userName}</span>
<span className="text-sm text-gray-500">{dealer.region}</span> <span className="text-sm text-gray-500 flex items-center">
</div>
<div className="text-sm text-gray-500 flex items-center">
<Phone className="h-3 w-3 mr-1" /> <Phone className="h-3 w-3 mr-1" />
{dealer.phone} {user.phonenumber}
</span>
</div> </div>
</label> </label>
</div> </div>
))} )
})}
</div> </div>
</div> </div>
</div> </div>
<DialogFooter> <DialogFooter>
<Button variant="outline" onClick={() => setIsCreateDialogOpen(false)}> <Button variant="outline" onClick={() => setIsCreateDialogOpen(false)} disabled={loading}>
</Button> </Button>
<Button onClick={handleCreateService}></Button> <Button onClick={handleCreateService} disabled={loading}>
{loading ? "创建中..." : "创建服务"}
</Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
@@ -251,56 +363,125 @@ export default function ValueAddedServicesPage() {
<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>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{services.map((service) => ( {loading ? (
<TableRow>
<TableCell colSpan={7} className="text-center py-8">
...
</TableCell>
</TableRow>
) : services.length === 0 ? (
<TableRow>
<TableCell colSpan={7} className="text-center py-8 text-gray-500">
</TableCell>
</TableRow>
) : (
services.map((service) => (
<TableRow key={service.id}> <TableRow key={service.id}>
<TableCell className="font-medium">{service.title}</TableCell> <TableCell className="font-medium">{service.serviceTitle}</TableCell>
<TableCell className="max-w-xs truncate">{service.description}</TableCell> <TableCell className="max-w-xs truncate">{service.description}</TableCell>
<TableCell> <TableCell>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Switch <Switch
checked={service.status === "active"} checked={service.status === "1"}
onCheckedChange={() => toggleServiceStatus(service.id)} onCheckedChange={() => toggleServiceStatus(service)}
disabled={loading}
/> />
<Badge variant={service.status === "active" ? "default" : "secondary"}> <Badge variant={service.status === "1" ? "default" : "secondary"}>
{service.status === "active" ? "上架" : "下架"} {service.status === "1" ? "上架" : "下架"}
</Badge> </Badge>
</div> </div>
</TableCell> </TableCell>
<TableCell> <TableCell>
<div className="flex flex-wrap gap-1"> <div className="flex flex-wrap gap-1">
{service.assignedDealers.slice(0, 2).map((dealerId) => ( {getUsersByIds(service.assignedAdmin || "").length > 0 ? (
<Badge key={dealerId} variant="outline" className="text-xs"> <>
{getDealerName(dealerId)} {getUsersByIds(service.assignedAdmin).slice(0, 2).map((userId) => (
</Badge> <Badge key={userId} variant="outline" className="text-xs">
))} {getUserName(userId, adminUsers)}
{service.assignedDealers.length > 2 && ( </Badge>
<Badge variant="outline" className="text-xs"> ))}
+{service.assignedDealers.length - 2} {getUsersByIds(service.assignedAdmin).length > 2 && (
</Badge> <Badge variant="outline" className="text-xs">
)} +{getUsersByIds(service.assignedAdmin).length - 2}
</div> </Badge>
</TableCell> )}
<TableCell>{service.createdAt}</TableCell> </>
) : (
<span className="text-xs text-gray-400">-</span>
)}
</div>
</TableCell>
<TableCell>
<div className="flex flex-wrap gap-1">
{getUsersByIds(service.assignedCommon || "").length > 0 ? (
<>
{getUsersByIds(service.assignedCommon).slice(0, 2).map((userId) => (
<Badge key={userId} variant="outline" className="text-xs">
{getUserName(userId, commonUsers)}
</Badge>
))}
{getUsersByIds(service.assignedCommon).length > 2 && (
<Badge variant="outline" className="text-xs">
+{getUsersByIds(service.assignedCommon).length - 2}
</Badge>
)}
</>
) : (
<span className="text-xs text-gray-400">-</span>
)}
</div>
</TableCell>
<TableCell>{service.createdTime || "-"}</TableCell>
<TableCell> <TableCell>
<div className="flex space-x-2"> <div className="flex space-x-2">
<Button variant="outline" size="sm" onClick={() => openEditDialog(service)}> <Button variant="outline" size="sm" onClick={() => openEditDialog(service)} disabled={loading}>
<Edit className="h-4 w-4" /> <Edit className="h-4 w-4" />
</Button> </Button>
<Button variant="outline" size="sm" onClick={() => handleDeleteService(service.id)}> <Button variant="outline" size="sm" onClick={() => handleDeleteService(service.id)} disabled={loading}>
<Trash2 className="h-4 w-4" /> <Trash2 className="h-4 w-4" />
</Button> </Button>
</div> </div>
</TableCell> </TableCell>
</TableRow> </TableRow>
))} ))
)}
</TableBody> </TableBody>
</Table> </Table>
{/* Pagination */}
<div className="flex items-center justify-between mt-4">
<div className="text-sm text-gray-600">
{total} {pageNum} / {totalPages || 1}
</div>
<div className="flex gap-2">
<Button
variant="outline"
size="sm"
onClick={handlePrevPage}
disabled={pageNum === 1 || loading}
>
<ChevronLeft className="h-4 w-4 mr-1" />
</Button>
<Button
variant="outline"
size="sm"
onClick={handleNextPage}
disabled={pageNum >= totalPages || loading}
>
<ChevronRight className="h-4 w-4 ml-1" />
</Button>
</div>
</div>
</CardContent> </CardContent>
</Card> </Card>
@@ -316,8 +497,8 @@ export default function ValueAddedServicesPage() {
<Label htmlFor="edit-title"></Label> <Label htmlFor="edit-title"></Label>
<Input <Input
id="edit-title" id="edit-title"
value={formData.title} value={formData.serviceTitle}
onChange={(e) => setFormData({ ...formData, title: e.target.value })} onChange={(e) => setFormData({ ...formData, serviceTitle: e.target.value })}
placeholder="请输入服务标题" placeholder="请输入服务标题"
/> />
</div> </div>
@@ -331,49 +512,96 @@ export default function ValueAddedServicesPage() {
rows={3} rows={3}
/> />
</div> </div>
<div>
<Label></Label>
<div className="grid grid-cols-1 gap-2 mt-2 max-h-48 overflow-y-auto border rounded p-2">
{adminUsers.map((user) => {
const assignedIds = formData.assignedAdmin.split(",").filter(Boolean)
const userId = user.userId
return (
<div key={userId} className="flex items-center space-x-2 p-2 border rounded">
<input
type="checkbox"
id={`edit-admin-${userId}`}
checked={assignedIds.includes(userId)}
onChange={(e) => {
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(","),
})
}
}}
/>
<label htmlFor={`edit-admin-${userId}`} className="flex-1 cursor-pointer">
<div className="flex justify-between">
<span className="font-medium">{user.nickName || user.userName}</span>
<span className="text-sm text-gray-500 flex items-center">
<Phone className="h-3 w-3 mr-1" />
{user.phonenumber}
</span>
</div>
</label>
</div>
)
})}
</div>
</div>
<div> <div>
<Label></Label> <Label></Label>
<div className="grid grid-cols-1 gap-2 mt-2"> <div className="grid grid-cols-1 gap-2 mt-2 max-h-48 overflow-y-auto border rounded p-2">
{dealers.map((dealer) => ( {commonUsers.map((user) => {
<div key={dealer.id} className="flex items-center space-x-2 p-2 border rounded"> const assignedIds = formData.assignedCommon.split(",").filter(Boolean)
<input const userId = user.userId
type="checkbox" return (
id={`edit-${dealer.id}`} <div key={userId} className="flex items-center space-x-2 p-2 border rounded">
checked={formData.assignedDealers.includes(dealer.id)} <input
onChange={(e) => { type="checkbox"
if (e.target.checked) { id={`edit-common-${userId}`}
setFormData({ checked={assignedIds.includes(userId)}
...formData, onChange={(e) => {
assignedDealers: [...formData.assignedDealers, dealer.id], const ids = formData.assignedCommon.split(",").filter(Boolean)
}) if (e.target.checked) {
} else { setFormData({
setFormData({ ...formData,
...formData, assignedCommon: [...ids, userId].join(","),
assignedDealers: formData.assignedDealers.filter((id) => id !== dealer.id), })
}) } else {
} setFormData({
}} ...formData,
/> assignedCommon: ids.filter((id) => id !== userId).join(","),
<label htmlFor={`edit-${dealer.id}`} className="flex-1 cursor-pointer"> })
}
}}
/>
<label htmlFor={`edit-common-${userId}`} className="flex-1 cursor-pointer">
<div className="flex justify-between"> <div className="flex justify-between">
<span className="font-medium">{dealer.name}</span> <span className="font-medium">{user.nickName || user.userName}</span>
<span className="text-sm text-gray-500">{dealer.region}</span> <span className="text-sm text-gray-500 flex items-center">
</div>
<div className="text-sm text-gray-500 flex items-center">
<Phone className="h-3 w-3 mr-1" /> <Phone className="h-3 w-3 mr-1" />
{dealer.phone} {user.phonenumber}
</span>
</div> </div>
</label> </label>
</div> </div>
))} )
})}
</div> </div>
</div> </div>
</div> </div>
<DialogFooter> <DialogFooter>
<Button variant="outline" onClick={() => setIsEditDialogOpen(false)}> <Button variant="outline" onClick={() => setIsEditDialogOpen(false)} disabled={loading}>
</Button> </Button>
<Button onClick={handleEditService}></Button> <Button onClick={handleEditService} disabled={loading}>
{loading ? "保存中..." : "保存修改"}
</Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>

View File

@@ -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<ServiceListResponse> {
try {
const queryParams = new URLSearchParams({
pageSize: params.pageSize.toString(),
pageNum: params.pageNum.toString(),
})
return await apiGet<ServiceListResponse>(`/back/services/list?${queryParams}`)
} catch (error) {
console.error('Failed to fetch services:', error)
throw error
}
}
export async function createService(data: ServiceCreateParams): Promise<ServiceResponse> {
try {
return await apiPost<ServiceResponse>('/back/services/', data)
} catch (error) {
console.error('Failed to create service:', error)
throw error
}
}
export async function updateService(data: ServiceUpdateParams): Promise<ServiceResponse> {
try {
return await apiPut<ServiceResponse>('/back/services/', data)
} catch (error) {
console.error('Failed to update service:', error)
throw error
}
}
export async function deleteService(id: string): Promise<ServiceResponse> {
try {
return await apiDelete<ServiceResponse>(`/back/services/${id}`)
} catch (error) {
console.error('Failed to delete service:', error)
throw error
}
}

12
src/lib/services/user.ts Normal file
View File

@@ -0,0 +1,12 @@
import { UserByRoleResponse } from '@/lib/types/user'
import { apiGet } from './api'
export async function getUserByRoleKey(roleKey: string): Promise<UserByRoleResponse> {
try {
return await apiGet<UserByRoleResponse>(`/back/user/getUserByRoleKey?roleKey=${roleKey}`)
} catch (error) {
console.error(`Failed to fetch users with role ${roleKey}:`, error)
throw error
}
}

45
src/lib/types/service.ts Normal file
View File

@@ -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
}

44
src/lib/types/user.ts Normal file
View File

@@ -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[]
}