fix: 3 критических исправления - OCR прогресс, условные поля, убран некорректный статус

1.  OCR Progress Bar:
   - Добавлен polling OCR результатов каждые 3 сек
   - Визуальный индикатор: 🔍 Обработка OCR... (1/10)
   - Progress bar с анимацией
   - Статусы: 🔄 Запуск → 🔍 Обработка →  Завершен
   - Gemini Vision результаты в Debug панели

2.  Убран некорректный 'Полис найден':
   - Было: показывался сразу после загрузки файла
   - Проблема: OCR еще не закончился, может быть шляпа
   - Решение: убрана зеленая плашка с Step2
   - Статус полиса только после реальной проверки

3.  Условные поля для стыковочного рейса:
   - Если выбран 'miss_connection' → показываются 4 доп поля:
     • Номер рейса прибытия
     • Дата рейса прибытия
     • Номер рейса отправления
     • Дата рейса отправления
   - Если выбран 'cancel_flight' → доп поле:
     • Подтверждение отмены от АК
   - Для обычных рейсов: только номер рейса

Frontend изменения:
- Step1Policy: OCR polling, progress bar
- Step2Details: условная логика полей (как в erv_ticket)
- useState для eventType
- handleEventTypeChange для динамики

Теперь:
 Видно прогресс OCR
 Видно результаты Gemini Vision
 Условные поля работают
 Нет ложных статусов
This commit is contained in:
AI Assistant
2025-10-25 10:12:41 +03:00
parent ddca18716d
commit a26cb772f5
2 changed files with 202 additions and 52 deletions

View File

@@ -87,6 +87,17 @@ export default function Step2Details({ formData, updateFormData, onNext, onPrev,
setFileList(newFileList);
};
const [eventType, setEventType] = useState(formData.eventType || '');
const handleEventTypeChange = (value: string) => {
setEventType(value);
form.setFieldValue('eventType', value);
};
// Проверяем нужны ли дополнительные поля для стыковочного рейса
const showConnectionFields = eventType === 'miss_connection';
const showCancelFlightDocs = eventType === 'cancel_flight';
return (
<Form
form={form}
@@ -94,21 +105,6 @@ export default function Step2Details({ formData, updateFormData, onNext, onPrev,
initialValues={formData}
style={{ marginTop: 24 }}
>
{/* Индикатор что полис найден */}
{formData.voucher && (
<div style={{
padding: 12,
background: '#f6ffed',
border: '1px solid #b7eb8f',
borderRadius: 8,
marginBottom: 24,
color: '#52c41a',
fontWeight: 500
}}>
Полис найден
</div>
)}
<Form.Item
label="Выберите тип события"
name="eventType"
@@ -117,6 +113,7 @@ export default function Step2Details({ formData, updateFormData, onNext, onPrev,
<Select
placeholder="Выберите тип события"
size="large"
onChange={handleEventTypeChange}
>
{EVENT_TYPES.map(type => (
<Option key={type.value} value={type.value}>
@@ -140,16 +137,107 @@ export default function Step2Details({ formData, updateFormData, onNext, onPrev,
/>
</Form.Item>
<Form.Item
label="Номер рейса/поезда/парома"
name="transportNumber"
rules={[{ required: true, message: 'Введите номер' }]}
>
<Input
placeholder="Введите номер"
size="large"
/>
</Form.Item>
{/* Для стыковочного рейса - номер рейса прибытия */}
{showConnectionFields && (
<Form.Item
label="Укажите номер рейса прибытия"
name="arrivalFlightNumber"
rules={[{ required: true, message: 'Введите номер рейса прибытия' }]}
>
<Input
placeholder="Введите номер"
size="large"
/>
</Form.Item>
)}
{showConnectionFields && (
<Form.Item
label="Дата рейса прибытия"
name="arrivalFlightDate"
rules={[{ required: true, message: 'Укажите дату прибытия' }]}
>
<DatePicker
placeholder="Выберите дату"
size="large"
style={{ width: '100%' }}
format="DD.MM.YYYY"
disabledDate={(current) => current && current > dayjs().endOf('day')}
/>
</Form.Item>
)}
{/* Для стыковочного рейса - номер рейса отправления */}
{showConnectionFields && (
<Form.Item
label="Укажите номер рейса отправления"
name="departureFlightNumber"
rules={[{ required: true, message: 'Введите номер рейса отправления' }]}
>
<Input
placeholder="Введите номер рейса отправления"
size="large"
/>
</Form.Item>
)}
{showConnectionFields && (
<Form.Item
label="Дата рейса отправления"
name="departureFlightDate"
rules={[{ required: true, message: 'Укажите дату отправления' }]}
>
<DatePicker
placeholder="Выберите дату"
size="large"
style={{ width: '100%' }}
format="DD.MM.YYYY"
disabledDate={(current) => current && current > dayjs().endOf('day')}
/>
</Form.Item>
)}
{/* Для обычных рейсов */}
{!showConnectionFields && (
<Form.Item
label="Номер рейса/поезда/парома"
name="transportNumber"
rules={[{ required: true, message: 'Введите номер' }]}
>
<Input
placeholder="Введите номер"
size="large"
/>
</Form.Item>
)}
{/* Дополнительные документы для отмены рейса */}
{showCancelFlightDocs && (
<Form.Item
label="Подтверждение уведомления об отмене рейса от АК"
name="cancelConfirmation"
tooltip="Уведомление от авиакомпании об отмене"
>
<Upload
listType="picture"
beforeUpload={(file) => {
const isLt15M = file.size / 1024 / 1024 < 15;
if (!isLt15M) {
message.error(`${file.name}: файл больше 15MB`);
return Upload.LIST_IGNORE;
}
return false;
}}
accept="image/*,.pdf,.heic,.heif"
multiple
maxCount={5}
>
<Button icon={<UploadOutlined />} size="large" block>
Загрузить подтверждение отмены
</Button>
</Upload>
</Form.Item>
)}
<Form.Item
label="Подтверждающие документы"