|
|
@@ -0,0 +1,516 @@
|
|
|
+import React, { useState, useEffect } from 'react';
|
|
|
+import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
|
+import { Button } from '@d8d/shared-ui-components/components/ui/button';
|
|
|
+import {
|
|
|
+ Dialog,
|
|
|
+ DialogContent,
|
|
|
+ DialogDescription,
|
|
|
+ DialogFooter,
|
|
|
+ DialogHeader,
|
|
|
+ DialogTitle,
|
|
|
+} from '@d8d/shared-ui-components/components/ui/dialog';
|
|
|
+import {
|
|
|
+ Card,
|
|
|
+ CardContent,
|
|
|
+ CardDescription,
|
|
|
+ CardHeader,
|
|
|
+ CardTitle,
|
|
|
+} from '@d8d/shared-ui-components/components/ui/card';
|
|
|
+import {
|
|
|
+ Table,
|
|
|
+ TableBody,
|
|
|
+ TableCell,
|
|
|
+ TableHead,
|
|
|
+ TableHeader,
|
|
|
+ TableRow,
|
|
|
+} from '@d8d/shared-ui-components/components/ui/table';
|
|
|
+import {
|
|
|
+ Select,
|
|
|
+ SelectContent,
|
|
|
+ SelectItem,
|
|
|
+ SelectTrigger,
|
|
|
+ SelectValue,
|
|
|
+} from '@d8d/shared-ui-components/components/ui/select';
|
|
|
+import { Badge } from '@d8d/shared-ui-components/components/ui/badge';
|
|
|
+import { Input } from '@d8d/shared-ui-components/components/ui/input';
|
|
|
+import { Separator } from '@d8d/shared-ui-components/components/ui/separator';
|
|
|
+import { toast } from 'sonner';
|
|
|
+import { Users, FileText, Calendar, Play, CheckCircle, X } from 'lucide-react';
|
|
|
+import { OrderStatus, WorkStatus, getOrderStatusLabel, getWorkStatusLabel } from '@d8d/allin-enums';
|
|
|
+import { orderClient, orderClientManager } from '../api/orderClient';
|
|
|
+import PersonSelector from './PersonSelector';
|
|
|
+import OrderPersonAssetAssociation from './OrderPersonAssetAssociation';
|
|
|
+import type { OrderDetail } from '../api/types';
|
|
|
+
|
|
|
+interface OrderDetailModalProps {
|
|
|
+ open: boolean;
|
|
|
+ onOpenChange: (open: boolean) => void;
|
|
|
+ orderId: number | null;
|
|
|
+ onSuccess?: () => void;
|
|
|
+}
|
|
|
+
|
|
|
+const OrderDetailModal: React.FC<OrderDetailModalProps> = ({
|
|
|
+ open,
|
|
|
+ onOpenChange,
|
|
|
+ orderId,
|
|
|
+ onSuccess,
|
|
|
+}) => {
|
|
|
+ const queryClient = useQueryClient();
|
|
|
+ const [isPersonSelectorOpen, setIsPersonSelectorOpen] = useState(false);
|
|
|
+ const [isAssetAssociationOpen, setIsAssetAssociationOpen] = useState(false);
|
|
|
+ const [selectedPersonId, setSelectedPersonId] = useState<number | null>(null);
|
|
|
+ const [isActionLoading, setIsActionLoading] = useState(false);
|
|
|
+
|
|
|
+ // 查询订单详情
|
|
|
+ const { data: order, isLoading, error, refetch } = useQuery({
|
|
|
+ queryKey: ['orderDetail', orderId],
|
|
|
+ queryFn: async () => {
|
|
|
+ if (!orderId) return null;
|
|
|
+ const response = await orderClientManager.get().detail[':id'].$get({
|
|
|
+ param: { id: orderId },
|
|
|
+ });
|
|
|
+ if (!response.ok) {
|
|
|
+ const errorData = await response.json();
|
|
|
+ throw new Error(errorData.message || '获取订单详情失败');
|
|
|
+ }
|
|
|
+ return await response.json();
|
|
|
+ },
|
|
|
+ enabled: open && !!orderId,
|
|
|
+ });
|
|
|
+
|
|
|
+ // 激活订单
|
|
|
+ const activateMutation = useMutation({
|
|
|
+ mutationFn: async (orderId: number) => {
|
|
|
+ const response = await orderClientManager.get().activate[':orderId'].$post({
|
|
|
+ param: { orderId },
|
|
|
+ });
|
|
|
+ if (!response.ok) {
|
|
|
+ const errorData = await response.json();
|
|
|
+ throw new Error(errorData.message || '激活订单失败');
|
|
|
+ }
|
|
|
+ return await response.json();
|
|
|
+ },
|
|
|
+ onSuccess: () => {
|
|
|
+ toast.success('订单激活成功');
|
|
|
+ refetch();
|
|
|
+ onSuccess?.();
|
|
|
+ },
|
|
|
+ onError: (error) => {
|
|
|
+ toast.error(error.message || '激活订单失败');
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ // 关闭订单
|
|
|
+ const closeMutation = useMutation({
|
|
|
+ mutationFn: async (orderId: number) => {
|
|
|
+ const response = await orderClientManager.get().close[':orderId'].$post({
|
|
|
+ param: { orderId },
|
|
|
+ });
|
|
|
+ if (!response.ok) {
|
|
|
+ const errorData = await response.json();
|
|
|
+ throw new Error(errorData.message || '关闭订单失败');
|
|
|
+ }
|
|
|
+ return await response.json();
|
|
|
+ },
|
|
|
+ onSuccess: () => {
|
|
|
+ toast.success('订单关闭成功');
|
|
|
+ refetch();
|
|
|
+ onSuccess?.();
|
|
|
+ },
|
|
|
+ onError: (error) => {
|
|
|
+ toast.error(error.message || '关闭订单失败');
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ // 更新人员工作状态
|
|
|
+ const updateWorkStatusMutation = useMutation({
|
|
|
+ mutationFn: async ({ orderId, personId, workStatus }: { orderId: number; personId: number; workStatus: WorkStatus }) => {
|
|
|
+ // 注意:这里需要根据实际API调整
|
|
|
+ // 原系统使用updatePersonWorkStatus,当前系统可能需要调用不同的API
|
|
|
+ // 暂时使用toast提示,实际实现需要根据后端API调整
|
|
|
+ throw new Error('更新工作状态API未实现');
|
|
|
+ },
|
|
|
+ onSuccess: () => {
|
|
|
+ toast.success('工作状态更新成功');
|
|
|
+ refetch();
|
|
|
+ },
|
|
|
+ onError: (error) => {
|
|
|
+ toast.error(error.message || '工作状态更新失败');
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ // 处理添加人员
|
|
|
+ const handleAddPersons = () => {
|
|
|
+ if (!orderId) return;
|
|
|
+ setIsPersonSelectorOpen(true);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理添加资产
|
|
|
+ const handleAddAsset = () => {
|
|
|
+ if (!orderId) return;
|
|
|
+ setIsAssetAssociationOpen(true);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理激活订单
|
|
|
+ const handleActivateOrder = () => {
|
|
|
+ if (!orderId) return;
|
|
|
+ setIsActionLoading(true);
|
|
|
+ activateMutation.mutate(orderId, {
|
|
|
+ onSettled: () => setIsActionLoading(false),
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理关闭订单
|
|
|
+ const handleCloseOrder = () => {
|
|
|
+ if (!orderId) return;
|
|
|
+ setIsActionLoading(true);
|
|
|
+ closeMutation.mutate(orderId, {
|
|
|
+ onSettled: () => setIsActionLoading(false),
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理更新工作状态
|
|
|
+ const handleUpdateWorkStatus = (personId: number, workStatus: WorkStatus) => {
|
|
|
+ if (!orderId) return;
|
|
|
+ updateWorkStatusMutation.mutate({ orderId, personId, workStatus });
|
|
|
+ };
|
|
|
+
|
|
|
+ // 获取订单状态徽章样式
|
|
|
+ const getOrderStatusBadge = (status: OrderStatus) => {
|
|
|
+ const variants = {
|
|
|
+ [OrderStatus.DRAFT]: 'secondary',
|
|
|
+ [OrderStatus.CONFIRMED]: 'default',
|
|
|
+ [OrderStatus.IN_PROGRESS]: 'default',
|
|
|
+ [OrderStatus.COMPLETED]: 'outline',
|
|
|
+ [OrderStatus.CANCELLED]: 'destructive',
|
|
|
+ } as const;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Badge variant={variants[status]}>
|
|
|
+ {getOrderStatusLabel(status)}
|
|
|
+ </Badge>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ // 获取工作状态徽章样式
|
|
|
+ const getWorkStatusBadge = (status: WorkStatus) => {
|
|
|
+ const variants = {
|
|
|
+ [WorkStatus.NOT_WORKING]: 'secondary',
|
|
|
+ [WorkStatus.PRE_WORKING]: 'default',
|
|
|
+ [WorkStatus.WORKING]: 'default',
|
|
|
+ [WorkStatus.RESIGNED]: 'destructive',
|
|
|
+ } as const;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Badge variant={variants[status]}>
|
|
|
+ {getWorkStatusLabel(status)}
|
|
|
+ </Badge>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ // 格式化日期
|
|
|
+ const formatDate = (dateString?: string) => {
|
|
|
+ if (!dateString) return '-';
|
|
|
+ try {
|
|
|
+ return new Date(dateString).toLocaleDateString('zh-CN');
|
|
|
+ } catch {
|
|
|
+ return dateString;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 人员列表表格列
|
|
|
+ const personColumns = [
|
|
|
+ { key: 'personId', label: 'ID', width: '60px' },
|
|
|
+ { key: 'personName', label: '姓名' },
|
|
|
+ { key: 'gender', label: '性别', width: '80px' },
|
|
|
+ { key: 'disabilityType', label: '残疾类型' },
|
|
|
+ { key: 'phone', label: '联系电话' },
|
|
|
+ { key: 'joinDate', label: '入职日期', width: '120px' },
|
|
|
+ { key: 'leaveDate', label: '离职日期', width: '120px' },
|
|
|
+ { key: 'workStatus', label: '工作状态', width: '120px' },
|
|
|
+ { key: 'salaryDetail', label: '薪资', width: '100px' },
|
|
|
+ ];
|
|
|
+
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Dialog open={open} onOpenChange={onOpenChange}>
|
|
|
+ <DialogContent className="max-w-6xl max-h-[90vh] overflow-y-auto" data-testid="order-detail-dialog">
|
|
|
+ <DialogHeader>
|
|
|
+ <DialogTitle data-testid="order-detail-dialog-title">订单详情</DialogTitle>
|
|
|
+ <DialogDescription data-testid="order-detail-dialog-description">
|
|
|
+ 查看订单完整信息和管理相关资源
|
|
|
+ </DialogDescription>
|
|
|
+ </DialogHeader>
|
|
|
+
|
|
|
+ {isLoading ? (
|
|
|
+ <div className="py-8 text-center">加载中...</div>
|
|
|
+ ) : error ? (
|
|
|
+ <div className="py-8 text-center text-destructive">
|
|
|
+ 加载失败: {error.message}
|
|
|
+ </div>
|
|
|
+ ) : order ? (
|
|
|
+ <div className="space-y-6">
|
|
|
+ {/* 订单信息卡片 */}
|
|
|
+ <Card>
|
|
|
+ <CardHeader>
|
|
|
+ <CardTitle>订单信息</CardTitle>
|
|
|
+ <CardDescription>订单基本信息和状态</CardDescription>
|
|
|
+ </CardHeader>
|
|
|
+ <CardContent>
|
|
|
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
|
+ <div className="space-y-2">
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">订单ID:</span>
|
|
|
+ <span data-testid="order-detail-id">{order.id}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">订单名称:</span>
|
|
|
+ <span data-testid="order-detail-name">{order.orderName}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">平台:</span>
|
|
|
+ <span data-testid="order-detail-platform">平台{order.platformId}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">公司:</span>
|
|
|
+ <span data-testid="order-detail-company">公司{order.companyId}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">渠道:</span>
|
|
|
+ <span data-testid="order-detail-channel">渠道{order.channelId || '-'}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className="space-y-2">
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">订单状态:</span>
|
|
|
+ <span data-testid="order-detail-status">{getOrderStatusBadge(order.orderStatus)}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">工作状态:</span>
|
|
|
+ <span data-testid="order-detail-work-status">{getWorkStatusBadge(order.workStatus)}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">预计开始日期:</span>
|
|
|
+ <span data-testid="order-detail-expected-start">{formatDate(order.expectedStartDate)}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">实际开始日期:</span>
|
|
|
+ <span data-testid="order-detail-actual-start">{formatDate(order.actualStartDate)}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">实际结束日期:</span>
|
|
|
+ <span data-testid="order-detail-actual-end">{formatDate(order.actualEndDate)}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <Separator className="my-4" />
|
|
|
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
|
+ <div className="space-y-2">
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">创建时间:</span>
|
|
|
+ <span data-testid="order-detail-create-time">{formatDate(order.createTime)}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">更新时间:</span>
|
|
|
+ <span data-testid="order-detail-update-time">{formatDate(order.updateTime)}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className="space-y-2">
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">联系人:</span>
|
|
|
+ <span data-testid="order-detail-contact-person">{order.contactPerson || '-'}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">联系电话:</span>
|
|
|
+ <span data-testid="order-detail-contact-phone">{order.contactPhone || '-'}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <span className="text-sm font-medium">地址:</span>
|
|
|
+ <span data-testid="order-detail-address">{order.address || '-'}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </CardContent>
|
|
|
+ </Card>
|
|
|
+
|
|
|
+ {/* 绑定人员列表 */}
|
|
|
+ <Card>
|
|
|
+ <CardHeader>
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
+ <div>
|
|
|
+ <CardTitle>绑定人员列表</CardTitle>
|
|
|
+ <CardDescription>已绑定到订单的人员信息</CardDescription>
|
|
|
+ </div>
|
|
|
+ <Button
|
|
|
+ onClick={handleAddPersons}
|
|
|
+ size="sm"
|
|
|
+ data-testid="order-detail-add-persons-button"
|
|
|
+ >
|
|
|
+ <Users className="mr-2 h-4 w-4" />
|
|
|
+ 添加人员
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </CardHeader>
|
|
|
+ <CardContent>
|
|
|
+ {order.orderPersons && order.orderPersons.length > 0 ? (
|
|
|
+ <div className="border rounded-md">
|
|
|
+ <Table>
|
|
|
+ <TableHeader>
|
|
|
+ <TableRow>
|
|
|
+ {personColumns.map((column) => (
|
|
|
+ <TableHead key={column.key} style={{ width: column.width }}>
|
|
|
+ {column.label}
|
|
|
+ </TableHead>
|
|
|
+ ))}
|
|
|
+ </TableRow>
|
|
|
+ </TableHeader>
|
|
|
+ <TableBody>
|
|
|
+ {order.orderPersons.map((person) => (
|
|
|
+ <TableRow key={person.personId} data-testid={`order-detail-person-${person.personId}`}>
|
|
|
+ <TableCell>{person.personId}</TableCell>
|
|
|
+ <TableCell>{person.personName}</TableCell>
|
|
|
+ <TableCell>{person.gender}</TableCell>
|
|
|
+ <TableCell>{person.disabilityType}</TableCell>
|
|
|
+ <TableCell>{person.phone}</TableCell>
|
|
|
+ <TableCell>{formatDate(person.joinDate)}</TableCell>
|
|
|
+ <TableCell>{formatDate(person.leaveDate)}</TableCell>
|
|
|
+ <TableCell>
|
|
|
+ <Select
|
|
|
+ value={person.workStatus?.toString()}
|
|
|
+ onValueChange={(value) => handleUpdateWorkStatus(person.personId, parseInt(value) as WorkStatus)}
|
|
|
+ data-testid={`order-detail-work-status-select-${person.personId}`}
|
|
|
+ >
|
|
|
+ <SelectTrigger className="w-full">
|
|
|
+ <SelectValue placeholder="选择状态" />
|
|
|
+ </SelectTrigger>
|
|
|
+ <SelectContent>
|
|
|
+ <SelectItem value={WorkStatus.NOT_WORKING} data-testid={`work-status-option-not-working-${person.personId}`}>
|
|
|
+ 未入职
|
|
|
+ </SelectItem>
|
|
|
+ <SelectItem value={WorkStatus.PRE_WORKING} data-testid={`work-status-option-pre-working-${person.personId}`}>
|
|
|
+ 已入职
|
|
|
+ </SelectItem>
|
|
|
+ <SelectItem value={WorkStatus.WORKING} data-testid={`work-status-option-working-${person.personId}`}>
|
|
|
+ 工作中
|
|
|
+ </SelectItem>
|
|
|
+ <SelectItem value={WorkStatus.RESIGNED} data-testid={`work-status-option-resigned-${person.personId}`}>
|
|
|
+ 已离职
|
|
|
+ </SelectItem>
|
|
|
+ </SelectContent>
|
|
|
+ </Select>
|
|
|
+ </TableCell>
|
|
|
+ <TableCell>¥{person.salaryDetail || 0}</TableCell>
|
|
|
+ </TableRow>
|
|
|
+ ))}
|
|
|
+ </TableBody>
|
|
|
+ </Table>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div className="text-center py-8 text-muted-foreground">
|
|
|
+ 暂无绑定人员
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </CardContent>
|
|
|
+ </Card>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div className="py-8 text-center text-muted-foreground">
|
|
|
+ 暂无订单数据
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <DialogFooter className="flex flex-col sm:flex-row sm:justify-between sm:space-x-2">
|
|
|
+ <div className="flex space-x-2">
|
|
|
+ <Button
|
|
|
+ onClick={handleAddPersons}
|
|
|
+ variant="outline"
|
|
|
+ data-testid="order-detail-bottom-add-persons-button"
|
|
|
+ >
|
|
|
+ <Users className="mr-2 h-4 w-4" />
|
|
|
+ 添加人员
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ onClick={handleAddAsset}
|
|
|
+ variant="outline"
|
|
|
+ data-testid="order-detail-bottom-add-asset-button"
|
|
|
+ >
|
|
|
+ <FileText className="mr-2 h-4 w-4" />
|
|
|
+ 资源上传
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ variant="outline"
|
|
|
+ data-testid="order-detail-bottom-attendance-button"
|
|
|
+ disabled // 出勤导出功能暂未实现
|
|
|
+ >
|
|
|
+ <Calendar className="mr-2 h-4 w-4" />
|
|
|
+ 出勤导出
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ <div className="flex space-x-2 mt-2 sm:mt-0">
|
|
|
+ <Button
|
|
|
+ variant="outline"
|
|
|
+ onClick={() => onOpenChange(false)}
|
|
|
+ data-testid="order-detail-close-button"
|
|
|
+ >
|
|
|
+ 关闭
|
|
|
+ </Button>
|
|
|
+ {order?.orderStatus === OrderStatus.DRAFT && (
|
|
|
+ <Button
|
|
|
+ onClick={handleActivateOrder}
|
|
|
+ disabled={isActionLoading}
|
|
|
+ data-testid="order-detail-activate-button"
|
|
|
+ >
|
|
|
+ <Play className="mr-2 h-4 w-4" />
|
|
|
+ {isActionLoading ? '激活中...' : '激活订单'}
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
+ {(order?.orderStatus === OrderStatus.CONFIRMED || order?.orderStatus === OrderStatus.IN_PROGRESS) && (
|
|
|
+ <Button
|
|
|
+ onClick={handleCloseOrder}
|
|
|
+ variant="destructive"
|
|
|
+ disabled={isActionLoading}
|
|
|
+ data-testid="order-detail-close-order-button"
|
|
|
+ >
|
|
|
+ <CheckCircle className="mr-2 h-4 w-4" />
|
|
|
+ {isActionLoading ? '关闭中...' : '关闭订单'}
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </DialogFooter>
|
|
|
+ </DialogContent>
|
|
|
+ </Dialog>
|
|
|
+
|
|
|
+ {/* 人员选择模态框 */}
|
|
|
+ {orderId && (
|
|
|
+ <PersonSelector
|
|
|
+ orderId={orderId}
|
|
|
+ open={isPersonSelectorOpen}
|
|
|
+ onOpenChange={setIsPersonSelectorOpen}
|
|
|
+ onSuccess={() => {
|
|
|
+ setIsPersonSelectorOpen(false);
|
|
|
+ refetch();
|
|
|
+ onSuccess?.();
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+
|
|
|
+ {/* 资产关联模态框 */}
|
|
|
+ {orderId && (
|
|
|
+ <OrderPersonAssetAssociation
|
|
|
+ orderId={orderId}
|
|
|
+ personId={selectedPersonId || undefined}
|
|
|
+ open={isAssetAssociationOpen}
|
|
|
+ onOpenChange={setIsAssetAssociationOpen}
|
|
|
+ onSuccess={() => {
|
|
|
+ setIsAssetAssociationOpen(false);
|
|
|
+ setSelectedPersonId(null);
|
|
|
+ refetch();
|
|
|
+ onSuccess?.();
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default OrderDetailModal;
|