import React, { useState, useEffect } from 'react'; import { Card, Table, Tag, Button, Space, Modal, Form, Input, Select, DatePicker, message, Tabs, Badge, Descriptions, Divider, List, Upload } from 'antd'; import { CheckOutlined, CloseOutlined, EyeOutlined, DollarOutlined, EditOutlined, UndoOutlined, ClockCircleOutlined, FileImageOutlined, UploadOutlined } from '@ant-design/icons'; import dayjs from 'dayjs'; import { useLanguageStore } from '../../store/languageStore'; const { TextArea } = Input; // 项目支出分类 const PROJECT_EXPENSE_CATEGORIES = [ { value: 'material_purchase', label: '材料采购' }, { value: 'equipment_purchase', label: '设备采购' }, { value: 'pole_crossarm', label: '电杆横担支出' }, { value: 'freight', label: '运费支出' }, { value: 'construction', label: '施工费支出' }, { value: 'other', label: '其他支出' } ]; // 公司支出分类 const COMPANY_EXPENSE_CATEGORIES = [ { value: 'office_operations', label: '通用运营(房租/耗材)' }, { value: 'transportation', label: '交通通勤' }, { value: 'marketing', label: '业扩营销' }, { value: 'power_system', label: '电力系统关系' }, { value: 'employee_welfare', label: '员工福利' }, { value: 'logistics', label: '快递物流' }, { value: 'other', label: '其他支出' } ]; // Type name to i18n key mapping const typeKeyMap: Record = { '预支申请': 'execution.advanceApply', '报销申请': 'execution.reimburseApply', '付款申请': 'execution.paymentApply', '核销申请': 'execution.verificationApply', '采购申请': 'execution.purchaseApply', }; // 执行记录类型 interface ExecutionRecord { id: string; applyCode: string; applyType: string; applicant: string; amount: number; currency: string; action: 'execute' | 'reject'; operator: string; operatorRole: string; timestamp: string; executeMethod?: string; voucherNo?: string; rejectReason?: string; remark?: string; } const ExecutionManagement: React.FC = () => { const { t, currentLanguage } = useLanguageStore(); const [loading, setLoading] = useState(false); const [detailModalVisible, setDetailModalVisible] = useState(false); const [editModalVisible, setEditModalVisible] = useState(false); const [selectedRecord, setSelectedRecord] = useState(null); const [fullDetail, setFullDetail] = useState(null); const [form] = Form.useForm(); const [editForm] = Form.useForm(); const [voucherFiles, setVoucherFiles] = useState([]); const [isRejecting, setIsRejecting] = useState(false); // 待执行数据 const [pendingData, setPendingData] = useState([]); // 已执行数据 const [executedData, setExecutedData] = useState([]); // 已执行列表筛选状态 const [searchKeyword, setSearchKeyword] = useState(''); const [filterType, setFilterType] = useState(null); const [sortField, setSortField] = useState('executeDate'); const [sortOrder, setSortOrder] = useState<'ascend' | 'descend'>('descend'); // 项目列表 const [projects, setProjects] = useState([]); // 从后端获取待执行数据 useEffect(() => { const fetchPendingData = async () => { setLoading(true); try { const response = await fetch('/api/executions/pending'); if (response.ok) { const data = await response.json(); if (data.success && Array.isArray(data.data)) { setPendingData(data.data.map((item: any, index: number) => ({ ...item, key: item.id || index, rawData: item }))); } else { message.error(t('execution.getPendingFailedFormat')); } } else { message.error(t('execution.getPendingFailed') + response.statusText); } } catch (error) { console.error('获取待执行数据错误:', error); message.error(t('execution.getPendingNetworkError')); } finally { setLoading(false); } }; fetchPendingData(); }, []); // 获取项目列表 useEffect(() => { const fetchProjects = async () => { try { const response = await fetch('/api/projects'); if (response.ok) { const data = await response.json(); if (data.success && Array.isArray(data.data)) { setProjects(data.data); } } } catch (error) { console.error('获取项目列表失败:', error); } }; fetchProjects(); }, []); // 从后端获取已执行数据 useEffect(() => { const fetchExecutedData = async () => { setLoading(true); try { const response = await fetch('/api/executions/executed'); if (response.ok) { const data = await response.json(); if (data.success && Array.isArray(data.data)) { setExecutedData(data.data.map((item: any, index: number) => ({ ...item, key: item.id || index, rawData: item }))); } else { message.error(t('execution.getExecutedFailedFormat')); } } else { message.error(t('execution.getExecutedFailed') + response.statusText); } } catch (error) { console.error('获取已执行数据错误:', error); message.error(t('execution.getExecutedNetworkError')); } finally { setLoading(false); } }; fetchExecutedData(); }, []); const formatAmount = (amount: number, currency: string = 'CNY') => { const symbols: Record = { CNY: '¥', USD: '$', LAK: '₭', THB: '฿' }; return (symbols[currency] || '¥') + (amount || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }; const formatNumberWithSeparator = (value: number | undefined, currency: string): string => { if (value === undefined || value === null) return ''; const symbols: Record = { CNY: '¥', USD: '$', LAK: '₭', THB: '฿' }; return (symbols[currency] || '¥') + value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }; const parseFormattedNumber = (value: string): number => { const cleaned = value.replace(/[¥$₭฿,]/g, ''); return parseFloat(cleaned) || 0; }; const getTypeTag = (type: string) => { const colors: Record = { '预支申请': 'blue', '报销申请': 'green', '付款申请': 'orange', '核销申请': 'purple', '采购申请': 'cyan' }; const key = typeKeyMap[type] || type; return {t(key)}; }; const getStatusTag = (status: string) => { const statusMap: Record = { pending: { color: 'processing', text: t('execution.pendingExecution') }, executed: { color: 'success', text: t('execution.executed') }, rejected: { color: 'error', text: t('execution.rejected') }, approved: { color: 'success', text: t('execution.approved') }, }; const config = statusMap[status] || { color: 'default', text: status }; return {config.text}; }; // 根据项目ID获取项目名称 const getProjectName = (projectId: any) => { if (!projectId) return '-'; const project = projects.find(p => p.id === projectId); return project ? project.name : `项目ID: ${projectId}`; }; // 查看详情 const handleViewDetail = async (record: any) => { setSelectedRecord(record); form.resetFields(); form.setFieldsValue({ execute_date: dayjs(), execute_method: 'bank' }); setVoucherFiles([]); setIsRejecting(false); // 获取完整详情 if (record.type === t('execution.purchaseApply')) { try { const response = await fetch(`/api/purchase-requests/${record.id}`); const data = await response.json(); if (data.success) { setFullDetail(data.data); } } catch (error) { console.error('获取采购申请详情失败:', error); // 如果获取失败,使用record中的数据 setFullDetail(record); } } else { // 其他类型使用record中的数据 setFullDetail(record); } setDetailModalVisible(true); }; // 处理执行 const handleExecute = async () => { try { // 检查是否为核销申请 const isVerification = selectedRecord.type === t('execution.verificationApply'); // 检查是否为退款类型的核销申请 const isRefundVerification = isVerification && fullDetail.settlement && fullDetail.settlement_amount > 0; // 检查是否为非结算核销 const isNonSettlementVerification = isVerification && !fullDetail.settlement; // 非结算核销不需要验证执行方式和付款凭证 if (isNonSettlementVerification) { // 直接执行,不需要验证表单 setLoading(true); // 调用执行API const executeResponse = await fetch('/api/executions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apply_id: selectedRecord.id, apply_type: 'verification', action: 'execute', execute_method: 'none', // 非结算核销不需要执行方式 voucher_files: [], // 非结算核销不需要付款凭证 remark: form.getFieldValue('remark') || '' }) }); if (executeResponse.ok) { setPendingData(pendingData.filter(item => item.key !== selectedRecord.key)); // 刷新已执行数据 const fetchExecutedData = async () => { try { const response = await fetch('/api/executions/executed'); if (response.ok) { const data = await response.json(); if (data.success && Array.isArray(data.data)) { setExecutedData(data.data.map((item: any, index: number) => ({ ...item, key: item.id || index, rawData: item }))); } } } catch (error) { console.error('获取已执行数据错误:', error); } }; fetchExecutedData(); message.success(t('execution.executeSuccess', { code: selectedRecord.code })); setDetailModalVisible(false); } else { message.error(t('execution.executeFailed')); } } else { // 其他类型的申请需要验证表单 const values = await form.validateFields(); // 检查是否需要上传付款凭证 if (!isRefundVerification && (!voucherFiles || voucherFiles.length === 0)) { message.error(t('execution.proofRequired')); return; } setLoading(true); // 获取已上传文件的URL列表(如果需要) let voucherFileUrls = []; if (!isRefundVerification) { voucherFileUrls = voucherFiles .map(f => f.url || f.response?.data?.url || f.response?.url) .filter(url => url); // 过滤掉空值 } // 调用执行API const executeResponse = await fetch('/api/executions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apply_id: selectedRecord.id, apply_type: selectedRecord.type === t('execution.advanceApply') ? 'advance' : selectedRecord.type === t('execution.reimburseApply') ? 'reimbursement' : selectedRecord.type === t('execution.paymentApply') ? 'payment' : selectedRecord.type === t('execution.purchaseApply') ? 'purchase' : 'verification', action: 'execute', execute_method: isRefundVerification ? 'refund' : values.execute_method, voucher_files: voucherFileUrls, remark: values.remark }) }); if (executeResponse.ok) { setPendingData(pendingData.filter(item => item.key !== selectedRecord.key)); // 刷新已执行数据 const fetchExecutedData = async () => { try { const response = await fetch('/api/executions/executed'); if (response.ok) { const data = await response.json(); if (data.success && Array.isArray(data.data)) { setExecutedData(data.data.map((item: any, index: number) => ({ ...item, key: item.id || index, rawData: item }))); } } } catch (error) { console.error('获取已执行数据错误:', error); } }; fetchExecutedData(); message.success(t('execution.executeSuccess', { code: selectedRecord.code })); setDetailModalVisible(false); } else { message.error(t('execution.executeFailed')); } } } catch (error) { console.error('执行操作失败:', error); message.error(t('common.networkError')); } finally { setLoading(false); } }; // 处理退回 const handleReject = async () => { try { setIsRejecting(true); // 只验证退回原因字段 const values = await form.validateFields(['rejectReason'], { force: true }); setLoading(true); // 调用退回API const rejectResponse = await fetch('/api/executions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apply_id: selectedRecord.id, apply_type: selectedRecord.type === t('execution.advanceApply') ? 'advance' : selectedRecord.type === t('execution.reimburseApply') ? 'reimbursement' : selectedRecord.type === t('execution.paymentApply') ? 'payment' : selectedRecord.type === t('execution.purchaseApply') ? 'purchase' : 'verification', action: 'reject', reject_reason: values.rejectReason }) }); if (rejectResponse.ok) { setPendingData(pendingData.filter(item => item.key !== selectedRecord.key)); message.success(t('execution.rejectSuccess', { code: selectedRecord.code })); setDetailModalVisible(false); } else { message.error(t('execution.rejectFailed')); } } catch (error) { console.error('退回操作失败:', error); message.error(t('common.networkError')); } finally { setLoading(false); } }; const handleEdit = (record: any) => { setSelectedRecord(record); editForm.setFieldsValue({ amount: record.amount, reason: record.reason }); setEditModalVisible(true); }; const handleEditSubmit = () => { editForm.validateFields().then(values => { message.success(t('execution.editSuccess')); setEditModalVisible(false); }); }; // 渲染附件列表 const renderAttachments = (attachments: any) => { // 处理字符串类型的 attachments(JSON字符串) let attachmentList = attachments; if (typeof attachments === 'string') { try { attachmentList = JSON.parse(attachments); } catch (e) { return null; } } // 确保是数组 if (!Array.isArray(attachmentList) || attachmentList.length === 0) return null; return (
{attachmentList.map((item: any, index: number) => { // 确保item是字符串类型的URL const url = typeof item === 'string' ? item : item?.url; if (!url) return null; return (
{url.match(/\.(jpg|jpeg|png|gif|webp)$/i) ? ( {`附件${index window.open(url, '_blank')} /> ) : (
)}
); })}
); }; // 获取支出分类的中文名称 const getCategoryName = (category: string) => { if (!category) return '-'; // 特殊分类映射 const specialCategories: Record = { // Project expense categories accommodation: t('execution.accommodation'), food: t('execution.catering'), fuel: t('execution.fuel'), materials: t('execution.scatteredMaterial'), customer_relations: t('execution.customerRelation'), subcontract_relations: t('execution.subcontractorRelation'), edl_relations: t('execution.EDLRelation'), extra_construction: t('execution.extraConstruction'), // Company expense categories general_operations: t('execution.generalOperation'), transportation: t('execution.commute'), business_expansion: t('execution.marketing'), power_system_relations: t('execution.powerSystem'), employee_benefits: t('execution.employeeBenefit'), express_logistics: t('execution.expressLogistics'), other: t('execution.otherCategory') }; // 先检查特殊分类 if (specialCategories[category]) return specialCategories[category]; // 再从项目支出分类中查找 const projectCategory = PROJECT_EXPENSE_CATEGORIES.find(c => c.value === category); if (projectCategory) return projectCategory.label; // 再从公司支出分类中查找 const companyCategory = COMPANY_EXPENSE_CATEGORIES.find(c => c.value === category); if (companyCategory) return companyCategory.label; // 如果都找不到,返回原始值 return category; }; // 渲染明细清单 const renderDetailItems = (detailItems: any) => { // 处理字符串类型的 detailItems(JSON字符串) let itemsList = detailItems; if (typeof detailItems === 'string') { try { itemsList = JSON.parse(detailItems); } catch (e) { return null; } } // 确保是数组 if (!Array.isArray(itemsList) || itemsList.length === 0) return null; return ( (
{t('execution.detailLabel', { index: index + 1 })} {item.description || getCategoryName(item.category) || '-'} {formatAmount(item.amount, item.currency)}
{item.category && (
{t('execution.categoryLabel')}{getCategoryName(item.category)}
)} {item.attachments && (
{t('execution.detailAttachment')} {renderAttachments(item.attachments)}
)}
)} /> ); }; const pendingColumns = [ { title: t('execution.subject'), dataIndex: 'reason', key: 'reason', ellipsis: true, render: (v: string, r: any) => handleViewDetail(r)}>{v} }, { title: t('execution.type'), dataIndex: 'type', key: 'type', width: 100, render: (v: string) => getTypeTag(v) }, { title: t('execution.applicant'), dataIndex: 'applicant', key: 'applicant', width: 80 }, { title: t('execution.amount'), dataIndex: 'amount', key: 'amount', width: 120, render: (v: number, r: any) => {formatAmount(v, r.currency)} }, { title: t('execution.payee'), dataIndex: 'payee', key: 'payee', ellipsis: true, render: (v: string, r: any) => v || r.applicant }, { title: t('execution.approvalDate'), dataIndex: 'approveDate', key: 'approveDate', width: 100 }, { title: t('execution.code'), dataIndex: 'code', key: 'code', width: 140 }, { title: t('execution.action'), key: 'action', width: 200, render: (_: any, record: any) => ( ) } ]; // 筛选和排序已执行数据 const getFilteredExecutedData = () => { let data = [...executedData]; // 按事由搜索 if (searchKeyword) { data = data.filter(item => (item.reason || '').toLowerCase().includes(searchKeyword.toLowerCase()) || (item.code || '').toLowerCase().includes(searchKeyword.toLowerCase()) || (item.applicant || '').toLowerCase().includes(searchKeyword.toLowerCase()) ); } // 按类型筛选 if (filterType) { data = data.filter(item => item.type === filterType); } // 排序 data.sort((a, b) => { let aValue = a[sortField]; let bValue = b[sortField]; // 处理日期排序 if (sortField === 'executeDate') { aValue = a.execute_date || a.executeDate || ''; bValue = b.execute_date || b.executeDate || ''; } if (sortOrder === 'ascend') { return aValue > bValue ? 1 : -1; } else { return aValue < bValue ? 1 : -1; } }); return data; }; const executedColumns = [ { title: t('execution.subject'), dataIndex: 'reason', key: 'reason', ellipsis: true, render: (v: string, r: any) => handleViewDetail(r)}>{v || '-'} }, { title: t('execution.type'), dataIndex: 'type', key: 'type', width: 100, render: (v: string) => getTypeTag(v) }, { title: t('execution.applicant'), dataIndex: 'applicant', key: 'applicant', width: 80 }, { title: t('execution.amount'), dataIndex: 'amount', key: 'amount', width: 140, render: (v: number, r: any) => ( <>
{formatAmount(v, r.currency)}
{r.currency !== 'CNY' && r.amount_cny &&
≈ ¥{r.amount_cny.toLocaleString('zh-CN', {minimumFractionDigits: 2})}
} ) }, { title: t('execution.executionDate'), dataIndex: 'executeDate', key: 'executeDate', width: 100, sorter: true, render: (v: string) => v || '-' }, { title: t('execution.executionMethod'), dataIndex: 'executeMethod', key: 'executeMethod', width: 100, render: (v: string) => v || '-' }, { title: t('execution.status'), dataIndex: 'status', key: 'status', width: 100, render: (v: string) => getStatusTag(v) }, { title: t('execution.code'), dataIndex: 'code', key: 'code', width: 140 }, ]; // 已执行列表的筛选和排序控件 const ExecutedListControls = () => (
setSearchKeyword(e.target.value)} onSearch={(value) => setSearchKeyword(value)} style={{ width: 250 }} allowClear />
); const tabItems = [ { key: 'pending', label: {t('execution.pendingTab')} , children: }, { key: 'executed', label: t('execution.executedTab'), children: ( <>
{ if (sorter.field) { setSortField(sorter.field); setSortOrder(sorter.order || 'descend'); } }} /> )}, ]; // 上传配置 const getUploadHeaders = () => { try { const authStorage = localStorage.getItem('auth-storage'); if (authStorage) { const parsed = JSON.parse(authStorage); const token = parsed?.state?.token; if (token) return { authorization: `Bearer ${token}` }; } } catch (e) {} return {}; }; const uploadProps = { name: 'file', action: '/api/upload/single', headers: getUploadHeaders(), onChange(info: any) { // 更新文件列表状态 setVoucherFiles(info.fileList); if (info.file.status === 'done') { message.success(t('execution.uploadSuccess', { name: info.file.name })); // 如果上传成功,将返回的URL添加到文件对象中 const updatedFileList = info.fileList.map((file: any) => { if (file.uid === info.file.uid && file.response) { return { ...file, url: file.response.data?.url || file.response.url || file.response }; } return file; }); setVoucherFiles(updatedFileList); } else if (info.file.status === 'error') { message.error(t('execution.uploadFailed', { name: info.file.name })); } }, fileList: voucherFiles, }; return (

{t('execution.title')}

{t('execution.description')}

{/* 详情模态框 */} setDetailModalVisible(false)} width={900} footer={ selectedRecord?.status === 'approved' || selectedRecord?.status === 'pending' ? (
) : ( ) } > {fullDetail && ( <> {/* 基本信息 */} {getTypeTag(selectedRecord.type)} {selectedRecord.code} {selectedRecord.applicant} {selectedRecord.date || fullDetail.advance_date || fullDetail.reimbursement_date || fullDetail.payment_date || fullDetail.verification_date} {formatAmount(selectedRecord.amount, selectedRecord.currency)} {selectedRecord.currency !== 'CNY' && fullDetail.amount_cny > 0 && ( ≈ ¥{fullDetail.amount_cny.toLocaleString('zh-CN', {minimumFractionDigits: 2})} )} {getStatusTag(selectedRecord.status)} {selectedRecord.reason} {/* 付款申请特有字段 */} {selectedRecord.type === t('execution.paymentApply') && ( <> {fullDetail.payee_type === 'subcontractor' ? t('execution.counterpartySubcontractor') : fullDetail.payee_type === 'supplier' ? t('execution.counterpartySupplier') : fullDetail.payee_type === 'customer' ? t('execution.counterpartyCustomer') : t('execution.counterpartyOther')} {fullDetail.payee || '-'} {fullDetail.bank_name || '-'} {fullDetail.bank_account || '-'} {fullDetail.expense_type === 'company' ? t('execution.companyExpense') : t('execution.projectExpense')} {fullDetail.expense_type === 'project' && fullDetail.project_id && ( {getProjectName(fullDetail.project_id)} )} {fullDetail.expense_type === 'project' ? (PROJECT_EXPENSE_CATEGORIES.find(c => c.value === fullDetail.expense_category)?.label || fullDetail.expense_category) : (COMPANY_EXPENSE_CATEGORIES.find(c => c.value === fullDetail.expense_category)?.label || fullDetail.expense_category) } )} {/* 报销申请特有字段 */} {selectedRecord.type === t('execution.reimburseApply') && fullDetail.expense_type && ( <> {fullDetail.expense_type === 'company' ? t('execution.companyExpense') : t('execution.projectExpense')} {fullDetail.project_id && ( {getProjectName(fullDetail.project_id)} )} )} {/* 核销申请特有字段 */} {selectedRecord.type === t('execution.verificationApply') && fullDetail.advance_code && ( <> {fullDetail.advance_code} {formatAmount(fullDetail.advance_amount, fullDetail.currency)} {fullDetail.settlement ? t('common.is') : t('common.no')} {formatAmount(fullDetail.total_reimbursed || 0, fullDetail.currency)} {formatAmount((fullDetail.advance_amount || 0) - (fullDetail.total_reimbursed || 0), fullDetail.currency)} {fullDetail.settlement && fullDetail.settlement_amount && ( {fullDetail.settlement_amount > 0 ? `${t('execution.refundText')}${formatAmount(fullDetail.settlement_amount, fullDetail.currency)}` : `${t('execution.supplementText')}${formatAmount(Math.abs(fullDetail.settlement_amount), fullDetail.currency)}`} )} )} {/* 采购申请特有字段 */} {selectedRecord.type === t('execution.purchaseApply') && ( <> {fullDetail.purchase_type === 'project' ? t('execution.projectPurchase') : t('execution.stockPurchase')} {fullDetail.purchase_type === 'project' && fullDetail.project_id && ( {getProjectName(fullDetail.project_id)} )} {fullDetail.supplier_name || '-'} {fullDetail.expense_category === 'material' ? t('execution.material') : fullDetail.expense_category === 'equipment' ? t('execution.equipment') : fullDetail.expense_category === 'pole' ? t('execution.pole') : t('execution.otherCategory')} {fullDetail.currency} {fullDetail.request_date} {fullDetail.brief_description || '-'} {fullDetail.remark && ( {fullDetail.remark} )} )} {/* 采购申请供应商收款信息 */} {selectedRecord.type === t('execution.purchaseApply') && fullDetail.supplier_payment_infos && fullDetail.supplier_payment_infos.length > 0 && ( <> {t('execution.supplierPaymentInfo')} {fullDetail.supplier_payment_infos.filter((p: any) => p.is_primary).map((payment: any, index: number) => ( {payment.account_name || '-'} {payment.bank_account || '-'} {payment.bank_name || '-'} {payment.qr_code && ( {t('execution.qrCode')} )} ))} )} {/* 采购申请商品明细 */} {selectedRecord.type === t('execution.purchaseApply') && fullDetail.items && fullDetail.items.length > 0 && ( <> {t('execution.purchaseDetail')} (
{index + 1}. {item.product_name} {fullDetail.currency} {item.total_price?.toLocaleString('zh-CN', {minimumFractionDigits: 2})}
{t('execution.specLabel')}{item.specification || '-'} | {t('execution.unitLabel')}{item.unit || '-'} | {t('execution.qtyLabel')}{item.quantity} | {t('execution.priceLabel')}{fullDetail.currency} {item.unit_price?.toLocaleString('zh-CN', {minimumFractionDigits: 2})}
)} /> )} {/* 明细清单 */} {fullDetail.detail_items && fullDetail.detail_items.length > 0 && ( <> {t('execution.detailList')} {renderDetailItems(fullDetail.detail_items)} )} {/* 审批意见 */} {fullDetail.approval_remark && ( <> {t('execution.approvalOpinion')}

{fullDetail.approval_remark}

)} {/* 申请凭证附件或退款凭证 */} {fullDetail.attachments && fullDetail.attachments.length > 0 && ( <> {fullDetail.settlement && fullDetail.settlement_amount > 0 ? t('execution.refundProof') : t('execution.applicationAttachment')} {renderAttachments(fullDetail.attachments)} )} {/* 执行表单 */} {(selectedRecord.status === 'approved' || selectedRecord.status === 'pending') && ( <> {t('execution.executionInfo')}
{/* 执行/确认日期 */} 0 ? t('execution.confirmationDate') : t('execution.executionDate')} rules={[{ required: true }]}> {/* 执行方式或收款方式 - 非结算核销不需要 */} {!(selectedRecord.type === t('execution.verificationApply') && !fullDetail.settlement) && ( selectedRecord.type === t('execution.verificationApply') && fullDetail.settlement && fullDetail.settlement_amount > 0 ? ( ) )} {/* 只有退款类型的核销申请和非结算核销不需要上传付款凭证,其他类型的申请都需要 */} {!(selectedRecord.type === t('execution.verificationApply') && (fullDetail.settlement && fullDetail.settlement_amount > 0 || !fullDetail.settlement)) && (
{t('execution.proofUploadTip')}
)} {/* 退款的核销申请显示提示 */} {selectedRecord.type === t('execution.verificationApply') && fullDetail.settlement && fullDetail.settlement_amount > 0 && (

{t('execution.noProofRefund')}

)} {/* 非结算核销的核销申请显示提示 */} {selectedRecord.type === t('execution.verificationApply') && !fullDetail.settlement && (

{t('execution.noProofNonSettlement')}

)} {/* 根据操作类型显示不同的字段 */} {!isRejecting ? ( // 执行操作时显示的字段 <> {/* 收款确认信息(仅退款类型)或备注 */} {selectedRecord.type === t('execution.verificationApply') && fullDetail.settlement && fullDetail.settlement_amount > 0 ? (