Эталоны

This commit is contained in:
2025-07-24 09:10:08 +03:00
parent 32e5cda438
commit 66b94cdd8f
12 changed files with 1674 additions and 467 deletions

View File

@@ -3,93 +3,20 @@ import { Button } from '@/component/ui/button'
import { Label } from '@/component/ui/label'
import { ElementDefinition } from '@/entitiy/element/model/interface'
import { CellTarget } from '@/type/template'
import { Settings, Weight, Wrench } from 'lucide-react'
import { FileText, Settings, Weight } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useStandards } from './hooks'
import { getStandardById } from './mockStandards'
import { StandardsEditor } from './StandardsEditor'
import { StandardsPreview } from './StandardsPreview'
import { StandardsSelector } from './StandardsSelector'
// Моковые данные для эталонов (такие же как в StandardsSelector)
const mockStandards = [
{
id: '1',
name: 'Эталон массы 1 кг',
shortName: 'ЭМ-1кг',
type: 'Масса',
registryNumber: 'ГРСИ 12345-01',
range: '0.5-2 кг',
accuracy: '±0.001 г',
certificateNumber: 'СИ-2024-001',
validUntil: '2025-12-31',
},
{
id: '2',
name: 'Эталон длины 1 м',
shortName: 'ЭД-1м',
type: 'Длина',
registryNumber: 'ГРСИ 12345-02',
range: '0.5-2 м',
accuracy: '±0.001 мм',
certificateNumber: 'СИ-2024-002',
validUntil: '2025-06-30',
},
{
id: '3',
name: 'Эталон температуры 20°C',
shortName: 'ЭТ-20°C',
type: 'Температура',
registryNumber: 'ГРСИ 12345-03',
range: '15-25°C',
accuracy: '±0.01°C',
certificateNumber: 'СИ-2024-003',
validUntil: '2025-03-15',
},
{
id: '4',
name: 'Эталон давления 1 Па',
shortName: 'ЭД-1Па',
type: 'Давление',
registryNumber: 'ГРСИ 12345-04',
range: '0.5-2 Па',
accuracy: '±0.001 Па',
certificateNumber: 'СИ-2024-004',
validUntil: '2025-09-20',
},
{
id: '5',
name: 'Эталон времени 1 с',
shortName: 'ЭВ-1с',
type: 'Время',
registryNumber: 'ГРСИ 12345-05',
range: '0.5-2 с',
accuracy: '±0.000001 с',
certificateNumber: 'СИ-2024-005',
validUntil: '2025-12-01',
},
]
// Функция для получения данных эталона по ID
const getStandardById = (id: string) => {
return mockStandards.find(standard => standard.id === id)
}
// Функция для получения типа эталона в сокращенном виде
const getStandardTypeBadge = (type: string) => {
switch (type) {
case 'Манометр грузопоршневой':
return 'МГП'
case 'Калибратор давления':
return 'КД'
default:
return 'МО'
}
}
interface StandardsConfig {
sheet: string // Лист Excel
startCell: string // Первая ячейка (например "A10")
maxItems: number // Обычно 7
targetCells: CellTarget[]
selectedStandards?: string[] // Выбранные эталоны (ID)
}
export const standardsDefinition: ElementDefinition<StandardsConfig, string[]> =
@@ -103,30 +30,30 @@ export const standardsDefinition: ElementDefinition<StandardsConfig, string[]> =
startCell: 'A1',
maxItems: 7,
targetCells: [],
selectedStandards: [], // По умолчанию пустой массив
},
Editor: StandardsEditor,
Preview: StandardsPreview,
Preview: StandardsPreview, // Использует моки для демонстрации
Render: ({ config, value, onChange }) => {
const [isStandardsDialogOpen, setIsStandardsDialogOpen] = useState(false)
const [selectedStandardIds, setSelectedStandardIds] = useState<string[]>(
[]
// Инициализируем из config.selectedStandards или value
config.selectedStandards || (Array.isArray(value) ? value : [])
)
// Если value содержит названия эталонов, находим соответствующие ID
useEffect(() => {
if (Array.isArray(value) && value.length > 0) {
const ids = value
.map(name => {
const standard = mockStandards.find(s => s.name === name)
return standard?.id || ''
})
.filter(Boolean)
setSelectedStandardIds(ids)
}
}, [value])
// Получаем реальные данные эталонов
const { data: standards = [] } = useStandards()
// Синхронизируем selectedStandardIds с config и value
useEffect(() => {
const standards =
config.selectedStandards || (Array.isArray(value) ? value : [])
setSelectedStandardIds(standards)
}, [config.selectedStandards, value])
// Получаем данные выбранных эталонов из реального API
const selectedStandardsData = selectedStandardIds
.map(id => getStandardById(id))
.map(id => standards.find(s => s.id === id))
.filter(Boolean)
return (
@@ -148,7 +75,7 @@ export const standardsDefinition: ElementDefinition<StandardsConfig, string[]> =
<div className="space-y-2">
{selectedStandardsData.length > 0 ? (
<div className="space-y-1.5">
<div className="space-y-1">
{selectedStandardsData.map(
(standard, index) =>
standard && (
@@ -156,25 +83,27 @@ export const standardsDefinition: ElementDefinition<StandardsConfig, string[]> =
key={standard.id}
className="flex items-center gap-2 rounded-md bg-muted/30 p-2 text-sm"
>
<div className="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10">
<div className="flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-primary/10">
<span className="text-xs font-medium text-primary">
{index + 1}
</span>
</div>
<div className="min-w-0 flex-1">
<div className="truncate text-xs font-medium text-foreground">
{standard.shortName}
{standard.name}
</div>
<div className="text-xs text-muted-foreground">
{standard.accuracy} {standard.range}
<div className="mt-0.5 flex items-center gap-1 text-xs text-muted-foreground">
<FileText className="h-2.5 w-2.5" />
<span className="hidden text-xs sm:inline">
{standard.registry_number}
</span>
</div>
</div>
<Badge
variant="secondary"
className="shrink-0 text-xs"
className="shrink-0 px-1.5 py-0.5 text-xs"
>
<Wrench className="mr-1 h-3 w-3" />
{getStandardTypeBadge(standard.type)}
{standard.range}
</Badge>
</div>
)
@@ -195,12 +124,10 @@ export const standardsDefinition: ElementDefinition<StandardsConfig, string[]> =
value={selectedStandardIds}
onChange={standardIds => {
setSelectedStandardIds(standardIds)
// Преобразуем ID эталонов в их названия для сохранения в ячейки
const standardNames = standardIds.map(
id => getStandardById(id)?.name || ''
)
onChange?.(standardNames)
// Сохраняем ID эталонов в value для записи в Excel
onChange?.(standardIds)
}}
maxItems={config.maxItems}
/>
</div>
)
@@ -213,8 +140,13 @@ export const standardsDefinition: ElementDefinition<StandardsConfig, string[]> =
// Используем targetCells из конфигурации
const cells = cfg.targetCells || []
// Сопоставляем значения с ячейками
const standardNames = Array.isArray(value) ? value : []
// Конвертируем ID эталонов в их названия для записи в Excel
// Здесь используем моки для быстрого доступа к данным при записи в Excel
const standardIds = Array.isArray(value) ? value : []
const standardNames = standardIds.map(
id => getStandardById(id)?.name || ''
)
return cells.map((target, idx) => ({
target,
value: standardNames[idx] || '', // Берем значение по индексу или пустую строку