починка багов

This commit is contained in:
2025-07-23 16:08:50 +03:00
parent 3fc352f8e9
commit 907b3e315e
24 changed files with 1249 additions and 1430 deletions

View File

@@ -3,6 +3,13 @@ import { Button } from '@/component/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/component/ui/card'
import { Input } from '@/component/ui/input'
import { Label } from '@/component/ui/label'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/component/ui/select'
import { ElementDefinition } from '@/entitiy/element/model/interface'
import {
AlertCircle,
@@ -412,6 +419,9 @@ function CalibrationCondInfo({
interface CalibrationConditionsConfig {
targetCells: any[]
defaultConditions?: CalibrationConditions
cellMapping?: {
[key: string]: string // параметр -> ячейка из targetCells (по индексу)
}
}
export const calibrationConditionsDefinition: ElementDefinition<
@@ -424,6 +434,7 @@ export const calibrationConditionsDefinition: ElementDefinition<
version: 1,
defaultConfig: {
targetCells: [],
cellMapping: {},
defaultConditions: {
temperature: '20',
humidity: '65',
@@ -433,164 +444,289 @@ export const calibrationConditionsDefinition: ElementDefinition<
lastUpdated: new Date().toISOString(),
},
},
mapToCells: () => {
// Генерируем ячейки для каждого параметра калибровки
const cells = [
{ sheet: 'L', cell: 'B2', displayName: 'Температура' },
{ sheet: 'L', cell: 'B3', displayName: 'Влажность' },
{ sheet: 'L', cell: 'B4', displayName: 'Давление' },
{ sheet: 'L', cell: 'B5', displayName: 'Напряжение' },
{ sheet: 'L', cell: 'B6', displayName: 'Частота' },
{ sheet: 'L', cell: 'B7', displayName: 'Дата обновления' },
]
return cells
mapToCells: cfg => {
// Используем только ячейки, указанные пользователем в targetCells
return cfg.targetCells || []
},
Editor: ({ config, onChange }) => (
<div className="space-y-4">
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4">
<p className="text-sm text-gray-600">
Элемент "Условия калибровки" позволяет вводить и отслеживать параметры
окружающей среды при проведении измерений. Поддерживает валидацию
значений и отслеживание времени обновления.
</p>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Параметры по умолчанию</label>
<div className="grid grid-cols-2 gap-4 rounded-lg border border-gray-200 p-4">
mapToCellValues: (config, value) => {
// Используем targetCells из конфигурации
const cells = config.targetCells || []
const cellMapping = config.cellMapping || {}
// Если значение не объект, возвращаем пустые значения
if (!value || typeof value !== 'object') {
return cells.map(target => ({
target,
value: '',
}))
}
// Создаем обратное сопоставление: индекс ячейки -> параметр
const reversedMapping: { [cellIndex: string]: string } = {}
Object.entries(cellMapping).forEach(([param, cellIndex]) => {
reversedMapping[cellIndex] = param
})
return cells.map((target, idx) => {
const paramKey = reversedMapping[idx.toString()]
const paramValue = paramKey ? (value as any)[paramKey] : ''
return {
target,
value: paramValue || '',
}
})
},
Editor: ({ config, onChange }) => {
const availableParams = [
{ key: 'temperature', label: 'Температура' },
{ key: 'humidity', label: 'Влажность' },
{ key: 'pressure', label: 'Давление' },
{ key: 'voltage', label: 'Напряжение' },
{ key: 'frequency', label: 'Частота' },
{ key: 'lastUpdated', label: 'Дата обновления' },
]
const targetCells = config.targetCells || []
const cellMapping = config.cellMapping || {}
// Функция для создания автоматического сопоставления по порядку
const createAutoMapping = () => {
const newMapping: { [key: string]: string } = {}
const paramKeys = availableParams.map(p => p.key)
// Сопоставляем первые N параметров с первыми N ячейками
targetCells.forEach((_, index) => {
if (index < paramKeys.length) {
newMapping[paramKeys[index]] = index.toString()
}
})
onChange({
...config,
cellMapping: newMapping,
})
}
const updateCellMapping = (param: string, cellIndex: string) => {
const newMapping = { ...cellMapping }
if (cellIndex === '' || cellIndex === 'none') {
delete newMapping[param]
} else {
newMapping[param] = cellIndex
}
onChange({
...config,
cellMapping: newMapping,
})
}
return (
<div className="space-y-4">
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4">
<p className="text-sm text-gray-600">
Элемент "Условия калибровки" позволяет вводить и отслеживать
параметры окружающей среды при проведении измерений. Поддерживает
валидацию значений и отслеживание времени обновления.
</p>
</div>
{/* Сопоставление параметров с ячейками */}
{targetCells.length > 0 && (
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Температура (°C)
</label>
<Input
type="number"
value={config.defaultConditions?.temperature || '20'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature: e.target.value,
humidity: config.defaultConditions?.humidity || '65',
pressure: config.defaultConditions?.pressure || '101.3',
voltage: config.defaultConditions?.voltage || '220',
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="20"
/>
<div className="flex items-center justify-between">
<Label className="text-sm font-medium">
Сопоставление с ячейками
</Label>
<Button
variant="outline"
size="sm"
onClick={createAutoMapping}
className="h-7 px-2 text-xs"
>
Автозаполнение
</Button>
</div>
<div className="space-y-3 rounded-lg border border-gray-200 p-4">
{availableParams.map(param => (
<div key={param.key} className="flex items-center gap-3">
<div className="min-w-[120px]">
<span className="text-sm text-gray-700">{param.label}</span>
</div>
<div className="flex-1">
<Select
value={cellMapping[param.key] || 'none'}
onValueChange={value =>
updateCellMapping(param.key, value)
}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Не указано" />
</SelectTrigger>
<SelectContent>
<SelectItem value="none">Не указано</SelectItem>
{targetCells.map((cell, index) => (
<SelectItem key={index} value={index.toString()}>
{cell.sheet}!{cell.cell}{' '}
{cell.displayName ? `(${cell.displayName})` : ''}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
))}
</div>
<p className="text-xs text-gray-500">
Настройте какой параметр условий калибровки будет записан в какую
ячейку. Используйте кнопку "Автозаполнение" для автоматического
сопоставления по порядку.
</p>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Влажность (%)
</label>
<Input
type="number"
value={config.defaultConditions?.humidity || '65'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature: config.defaultConditions?.temperature || '20',
humidity: e.target.value,
pressure: config.defaultConditions?.pressure || '101.3',
voltage: config.defaultConditions?.voltage || '220',
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="65"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Давление (кПа)
</label>
<Input
type="number"
value={config.defaultConditions?.pressure || '101.3'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature: config.defaultConditions?.temperature || '20',
humidity: config.defaultConditions?.humidity || '65',
pressure: e.target.value,
voltage: config.defaultConditions?.voltage || '220',
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="101.3"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Напряжение (В)
</label>
<Input
type="number"
value={config.defaultConditions?.voltage || '220'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature: config.defaultConditions?.temperature || '20',
humidity: config.defaultConditions?.humidity || '65',
pressure: config.defaultConditions?.pressure || '101.3',
voltage: e.target.value,
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="220"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Частота (Гц)
</label>
<Input
type="number"
value={config.defaultConditions?.frequency || '50'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature: config.defaultConditions?.temperature || '20',
humidity: config.defaultConditions?.humidity || '65',
pressure: config.defaultConditions?.pressure || '101.3',
voltage: config.defaultConditions?.voltage || '220',
frequency: e.target.value,
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="50"
/>
)}
<div className="space-y-2">
<label className="text-sm font-medium">Параметры по умолчанию</label>
<div className="grid grid-cols-2 gap-4 rounded-lg border border-gray-200 p-4">
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Температура (°C)
</label>
<Input
type="number"
value={config.defaultConditions?.temperature || '20'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature: e.target.value,
humidity: config.defaultConditions?.humidity || '65',
pressure: config.defaultConditions?.pressure || '101.3',
voltage: config.defaultConditions?.voltage || '220',
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="20"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Влажность (%)
</label>
<Input
type="number"
value={config.defaultConditions?.humidity || '65'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature:
config.defaultConditions?.temperature || '20',
humidity: e.target.value,
pressure: config.defaultConditions?.pressure || '101.3',
voltage: config.defaultConditions?.voltage || '220',
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="65"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Давление (кПа)
</label>
<Input
type="number"
value={config.defaultConditions?.pressure || '101.3'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature:
config.defaultConditions?.temperature || '20',
humidity: config.defaultConditions?.humidity || '65',
pressure: e.target.value,
voltage: config.defaultConditions?.voltage || '220',
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="101.3"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Напряжение (В)
</label>
<Input
type="number"
value={config.defaultConditions?.voltage || '220'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature:
config.defaultConditions?.temperature || '20',
humidity: config.defaultConditions?.humidity || '65',
pressure: config.defaultConditions?.pressure || '101.3',
voltage: e.target.value,
frequency: config.defaultConditions?.frequency || '50',
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="220"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-medium text-gray-600">
Частота (Гц)
</label>
<Input
type="number"
value={config.defaultConditions?.frequency || '50'}
onChange={e =>
onChange({
...config,
defaultConditions: {
...config.defaultConditions,
temperature:
config.defaultConditions?.temperature || '20',
humidity: config.defaultConditions?.humidity || '65',
pressure: config.defaultConditions?.pressure || '101.3',
voltage: config.defaultConditions?.voltage || '220',
frequency: e.target.value,
lastUpdated:
config.defaultConditions?.lastUpdated ||
new Date().toISOString(),
},
})
}
placeholder="50"
/>
</div>
</div>
</div>
</div>
</div>
),
)
},
Preview: ({ config }) => (
<div className="space-y-3">
<div className="text-sm font-medium text-gray-700">Предпросмотр</div>
@@ -613,6 +749,7 @@ export const calibrationConditionsDefinition: ElementDefinition<
</div>
),
Render: ({ config, value, onChange }) => {
// Если значение не установлено, используем defaultConditions из конфигурации
const conditions = value ||
config.defaultConditions || {
temperature: '20',