完善MECMAS21参数配置与分组交互
This commit is contained in:
1 parent
32f21f08ff
commit
be54070855
28 files changed
+3418
-202
No files matched your search
+361
-72
@@ -95,6 +95,7 @@ import {
|
||||
loadParameterColumnLayout,
|
||||
saveParameterColumnLayout,
|
||||
type ParameterColumnLayout,
|
||||
type ParameterTableGroup,
|
||||
type ParameterTableRow,
|
||||
} from "./ParameterTable";
|
||||
import {
|
||||
@@ -174,8 +175,9 @@ type ParameterDefinition = {
|
||||
min?: number;
|
||||
max?: number;
|
||||
minExclusive?: boolean;
|
||||
editor?: "amesimGasReference" | "amesimGasPropertyModel";
|
||||
editor?: "choice" | "amesimGasReference" | "amesimGasPropertyModel";
|
||||
options?: ParameterOption[];
|
||||
visibleWhen?: ParameterVisibilityCondition[];
|
||||
};
|
||||
|
||||
type ParameterOption = {
|
||||
@@ -183,6 +185,19 @@ type ParameterOption = {
|
||||
label: string;
|
||||
};
|
||||
|
||||
type ParameterVisibilityCondition = {
|
||||
parameter: string;
|
||||
values: number[];
|
||||
};
|
||||
|
||||
type ParameterGroupDefinition = {
|
||||
id: string;
|
||||
label: string;
|
||||
order: number;
|
||||
parameters: string[];
|
||||
defaultExpanded: boolean;
|
||||
};
|
||||
|
||||
type ComponentDefinition = {
|
||||
type: string;
|
||||
label: string;
|
||||
@@ -198,6 +213,7 @@ type ComponentDefinition = {
|
||||
role?: "amesimGasMediumDefinition";
|
||||
ports: PortDefinition[];
|
||||
parameters: Record<string, ParameterDefinition>;
|
||||
parameterGroups?: ParameterGroupDefinition[];
|
||||
};
|
||||
|
||||
type ComponentLibraryDefinition = {
|
||||
@@ -220,8 +236,9 @@ type ComponentCatalogParameterPayload = {
|
||||
minimum?: number;
|
||||
maximum?: number;
|
||||
minimumExclusive: boolean;
|
||||
editor?: "amesimGasReference" | "amesimGasPropertyModel";
|
||||
editor?: "choice" | "amesimGasReference" | "amesimGasPropertyModel";
|
||||
options?: ParameterOption[];
|
||||
visibleWhen?: ParameterVisibilityCondition[];
|
||||
};
|
||||
|
||||
type ComponentCatalogComponentPayload = {
|
||||
@@ -239,6 +256,13 @@ type ComponentCatalogComponentPayload = {
|
||||
role?: "amesimGasMediumDefinition";
|
||||
ports: Array<PortDefinition & { order: number }>;
|
||||
parameters: ComponentCatalogParameterPayload[];
|
||||
parameterGroups?: Array<{
|
||||
id: string;
|
||||
label: string;
|
||||
order: number;
|
||||
parameters: string[];
|
||||
defaultExpanded?: boolean;
|
||||
}>;
|
||||
};
|
||||
|
||||
type ComponentCatalogResponse = {
|
||||
@@ -313,7 +337,8 @@ type ProjectEdgePayload = {
|
||||
|
||||
type ReactFlowProjectPayload = {
|
||||
name: string;
|
||||
mediumReferenceVersion?: 1;
|
||||
mediumReferenceVersion?: 1 | null;
|
||||
amesimParameterEncodingVersion?: 1 | null;
|
||||
nodes: ProjectNodePayload[];
|
||||
edges: ProjectEdgePayload[];
|
||||
simulation: SimulationConfig;
|
||||
@@ -1055,6 +1080,58 @@ function normalizeComponentCatalog(payload: unknown): ComponentLibraryDefinition
|
||||
}
|
||||
componentTypes.add(component.type);
|
||||
|
||||
const parameters = Object.fromEntries(
|
||||
component.parameters.map((parameter) => {
|
||||
const visibleWhen = normalizeParameterVisibilityConditions(
|
||||
parameter.visibleWhen,
|
||||
);
|
||||
return [
|
||||
parameter.name,
|
||||
{
|
||||
label: parameter.label || parameter.name,
|
||||
...(typeof parameter.description === "string" &&
|
||||
parameter.description.trim()
|
||||
? { description: parameter.description.trim() }
|
||||
: {}),
|
||||
...(parameter.unit ? { unit: parameter.unit } : {}),
|
||||
...(parameter.quantity && parameter.quantity !== "dimensionless"
|
||||
? { quantity: parameter.quantity }
|
||||
: {}),
|
||||
default: parameter.default,
|
||||
...(parameter.minimum !== undefined
|
||||
? { min: parameter.minimum }
|
||||
: {}),
|
||||
...(parameter.maximum !== undefined
|
||||
? { max: parameter.maximum }
|
||||
: {}),
|
||||
...(parameter.minimumExclusive
|
||||
? { minExclusive: true }
|
||||
: {}),
|
||||
...(parameter.editor === "choice" ||
|
||||
parameter.editor === "amesimGasReference" ||
|
||||
parameter.editor === "amesimGasPropertyModel"
|
||||
? { editor: parameter.editor }
|
||||
: {}),
|
||||
...(Array.isArray(parameter.options)
|
||||
? {
|
||||
options: parameter.options.flatMap((option) =>
|
||||
Number.isFinite(Number(option?.value)) &&
|
||||
typeof option?.label === "string"
|
||||
? [{ value: Number(option.value), label: option.label }]
|
||||
: [],
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
...(visibleWhen ? { visibleWhen } : {}),
|
||||
},
|
||||
] as const;
|
||||
}),
|
||||
);
|
||||
const parameterGroups = normalizeParameterGroups(
|
||||
component.parameterGroups,
|
||||
new Set(Object.keys(parameters)),
|
||||
);
|
||||
|
||||
return {
|
||||
type: component.type,
|
||||
label: component.label,
|
||||
@@ -1080,46 +1157,8 @@ function normalizeComponentCatalog(payload: unknown): ComponentLibraryDefinition
|
||||
: {}),
|
||||
side: port.side,
|
||||
})),
|
||||
parameters: Object.fromEntries(
|
||||
component.parameters.map((parameter) => [
|
||||
parameter.name,
|
||||
{
|
||||
label: parameter.label || parameter.name,
|
||||
...(typeof parameter.description === "string" &&
|
||||
parameter.description.trim()
|
||||
? { description: parameter.description.trim() }
|
||||
: {}),
|
||||
...(parameter.unit ? { unit: parameter.unit } : {}),
|
||||
...(parameter.quantity && parameter.quantity !== "dimensionless"
|
||||
? { quantity: parameter.quantity }
|
||||
: {}),
|
||||
default: parameter.default,
|
||||
...(parameter.minimum !== undefined
|
||||
? { min: parameter.minimum }
|
||||
: {}),
|
||||
...(parameter.maximum !== undefined
|
||||
? { max: parameter.maximum }
|
||||
: {}),
|
||||
...(parameter.minimumExclusive
|
||||
? { minExclusive: true }
|
||||
: {}),
|
||||
...(parameter.editor === "amesimGasReference" ||
|
||||
parameter.editor === "amesimGasPropertyModel"
|
||||
? { editor: parameter.editor }
|
||||
: {}),
|
||||
...(Array.isArray(parameter.options)
|
||||
? {
|
||||
options: parameter.options.flatMap((option) =>
|
||||
Number.isFinite(Number(option?.value)) &&
|
||||
typeof option?.label === "string"
|
||||
? [{ value: Number(option.value), label: option.label }]
|
||||
: [],
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
]),
|
||||
),
|
||||
parameters,
|
||||
...(parameterGroups.length > 0 ? { parameterGroups } : {}),
|
||||
} satisfies ComponentDefinition;
|
||||
});
|
||||
|
||||
@@ -1193,11 +1232,44 @@ function defaultParameterUnits(definition: ComponentDefinition) {
|
||||
);
|
||||
}
|
||||
|
||||
function orderedParameterEntries(definition: ComponentDefinition) {
|
||||
return Object.entries(definition.parameters).sort(
|
||||
([firstKey], [secondKey]) =>
|
||||
Number(secondKey === "gi") - Number(firstKey === "gi"),
|
||||
function ungroupedParameterPriority(
|
||||
key: string,
|
||||
definition: ParameterDefinition,
|
||||
) {
|
||||
if (key === "gi") {
|
||||
return 0;
|
||||
}
|
||||
return definition.editor ? 1 : 2;
|
||||
}
|
||||
|
||||
function orderedParameterEntries(
|
||||
definition: ComponentDefinition,
|
||||
): Array<[string, ParameterDefinition]> {
|
||||
const entries = Object.entries(definition.parameters);
|
||||
const entryByName = new Map(entries);
|
||||
const groupedNames = new Set(
|
||||
definition.parameterGroups?.flatMap((group) => group.parameters) ?? [],
|
||||
);
|
||||
const ungroupedEntries = entries
|
||||
.map((entry, index) => ({ entry, index }))
|
||||
.filter(({ entry: [key] }) => !groupedNames.has(key))
|
||||
.sort(
|
||||
(first, second) =>
|
||||
ungroupedParameterPriority(first.entry[0], first.entry[1]) -
|
||||
ungroupedParameterPriority(second.entry[0], second.entry[1]) ||
|
||||
first.index - second.index,
|
||||
)
|
||||
.map(({ entry }) => entry);
|
||||
const groupedEntries =
|
||||
definition.parameterGroups?.flatMap((group) =>
|
||||
group.parameters.flatMap((name) => {
|
||||
const parameter = entryByName.get(name);
|
||||
return parameter
|
||||
? ([[name, parameter]] as Array<[string, ParameterDefinition]>)
|
||||
: [];
|
||||
}),
|
||||
) ?? [];
|
||||
return [...ungroupedEntries, ...groupedEntries];
|
||||
}
|
||||
|
||||
function buildNodeData(definition: ComponentDefinition): SimulationNodeData {
|
||||
@@ -1392,9 +1464,9 @@ function repairAmesimGasReferences(
|
||||
function migrateLegacyDefaultAmesimGasReference(
|
||||
nodes: SimulationNode[],
|
||||
componentDefinitions: ComponentDefinition[],
|
||||
mediumReferenceVersion: 1 | undefined,
|
||||
mediumReferenceVersion: 1 | null | undefined,
|
||||
): AmesimGasReferenceRepair {
|
||||
const hasVersionMarker = mediumReferenceVersion !== undefined;
|
||||
const hasVersionMarker = mediumReferenceVersion === 1;
|
||||
const hasMediumDefinition = nodes.some((node) =>
|
||||
isAmesimGasMediumDefinition(
|
||||
componentDefinitionForNode(node, componentDefinitions),
|
||||
@@ -4260,7 +4332,11 @@ function FlowWorkbench() {
|
||||
recordHistory();
|
||||
}
|
||||
const normalizedNodes = project.nodes.map((node) =>
|
||||
normalizeLoadedNode(node, componentDefinitions),
|
||||
normalizeLoadedNode(
|
||||
node,
|
||||
componentDefinitions,
|
||||
project.amesimParameterEncodingVersion,
|
||||
),
|
||||
);
|
||||
const indexedMedia = assignMissingAmesimGasDefinitionIndices(
|
||||
normalizedNodes,
|
||||
@@ -4993,8 +5069,11 @@ function FlowWorkbench() {
|
||||
readOnly: true,
|
||||
description: "系统为画布节点分配的稳定标识,用于工程数据和连接关系。",
|
||||
},
|
||||
...orderedParameterEntries(selectedDefinition).map(
|
||||
([key, definition]): ParameterTableRow => {
|
||||
...orderedParameterEntries(selectedDefinition)
|
||||
.filter(([, definition]) =>
|
||||
parameterIsVisible(definition, selectedNode.data.parameters),
|
||||
)
|
||||
.map(([key, definition]): ParameterTableRow => {
|
||||
const selectedUnit =
|
||||
selectedNode.data.parameterUnits[key] ?? definition.unit ?? "";
|
||||
const units = parameterUnitOptions(definition);
|
||||
@@ -5012,6 +5091,7 @@ function FlowWorkbench() {
|
||||
definition.editor === "amesimGasReference";
|
||||
const gasPropertyModel =
|
||||
definition.editor === "amesimGasPropertyModel";
|
||||
const genericChoice = definition.editor === "choice";
|
||||
const parameterLabel = mediumDefinitionIndex
|
||||
? "介质定义索引"
|
||||
: gasReference
|
||||
@@ -5025,21 +5105,20 @@ function FlowWorkbench() {
|
||||
amesimGasMediumOptions.some(
|
||||
(option) => option.value === gasReferenceIndex,
|
||||
);
|
||||
const propertyModelValue = Number(baseValue);
|
||||
const propertyModelAvailable =
|
||||
gasPropertyModel &&
|
||||
Number.isFinite(propertyModelValue) &&
|
||||
const optionValue = numericChoiceValue(baseValue);
|
||||
const optionAvailable =
|
||||
(gasPropertyModel || genericChoice) &&
|
||||
optionValue !== null &&
|
||||
(definition.options ?? []).some(
|
||||
(option) => option.value === propertyModelValue,
|
||||
(option) => option.value === optionValue,
|
||||
);
|
||||
const error =
|
||||
gasReference && !gasReferenceAvailable
|
||||
? "引用的介质定义不存在"
|
||||
: parameterValidationMessage(
|
||||
definition,
|
||||
baseValue,
|
||||
selectedUnit,
|
||||
);
|
||||
componentParameterValidationMessage(
|
||||
definition,
|
||||
baseValue,
|
||||
selectedUnit,
|
||||
gasReference ? amesimGasMediumOptions : undefined,
|
||||
);
|
||||
let valueControl: ReactNode;
|
||||
if (mediumDefinitionIndex) {
|
||||
valueControl = (
|
||||
@@ -5076,7 +5155,7 @@ function FlowWorkbench() {
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
} else if (gasPropertyModel) {
|
||||
} else if (gasPropertyModel || genericChoice) {
|
||||
valueControl = (
|
||||
<select
|
||||
aria-invalid={Boolean(error)}
|
||||
@@ -5087,12 +5166,14 @@ function FlowWorkbench() {
|
||||
}
|
||||
onFocus={recordHistory}
|
||||
value={
|
||||
propertyModelAvailable ? String(propertyModelValue) : ""
|
||||
optionAvailable ? String(optionValue) : ""
|
||||
}
|
||||
>
|
||||
{!propertyModelAvailable ? (
|
||||
{!optionAvailable ? (
|
||||
<option disabled value="">
|
||||
当前模型无效,请重新选择
|
||||
{gasPropertyModel
|
||||
? "当前模型无效,请重新选择"
|
||||
: "当前选项无效,请重新选择"}
|
||||
</option>
|
||||
) : null}
|
||||
{(definition.options ?? []).map((option) => (
|
||||
@@ -5160,10 +5241,61 @@ function FlowWorkbench() {
|
||||
selectedUnit,
|
||||
),
|
||||
};
|
||||
},
|
||||
),
|
||||
}),
|
||||
]
|
||||
: [];
|
||||
const componentParameterGroups: ParameterTableGroup[] =
|
||||
selectedNode && selectedDefinition
|
||||
? (selectedDefinition.parameterGroups ?? []).flatMap((group) => {
|
||||
const rowIds = group.parameters.flatMap((name) => {
|
||||
const definition = selectedDefinition.parameters[name];
|
||||
return definition &&
|
||||
parameterIsVisible(definition, selectedNode.data.parameters)
|
||||
? [`component-parameter-${name}`]
|
||||
: [];
|
||||
});
|
||||
const invalidParameters = group.parameters.filter((name) => {
|
||||
const definition = selectedDefinition.parameters[name];
|
||||
if (!definition) {
|
||||
return false;
|
||||
}
|
||||
const selectedUnit =
|
||||
selectedNode.data.parameterUnits[name] ?? definition.unit ?? "";
|
||||
const mediumDefinitionIndex =
|
||||
isAmesimGasMediumDefinition(selectedDefinition) && name === "gi";
|
||||
const gasReference =
|
||||
!mediumDefinitionIndex &&
|
||||
definition.editor === "amesimGasReference";
|
||||
return Boolean(
|
||||
componentParameterValidationMessage(
|
||||
definition,
|
||||
selectedNode.data.parameters[name] ?? "",
|
||||
selectedUnit,
|
||||
gasReference ? amesimGasMediumOptions : undefined,
|
||||
),
|
||||
);
|
||||
});
|
||||
const hiddenErrorCount = invalidParameters.filter((name) => {
|
||||
const definition = selectedDefinition.parameters[name];
|
||||
return (
|
||||
definition &&
|
||||
!parameterIsVisible(definition, selectedNode.data.parameters)
|
||||
);
|
||||
}).length;
|
||||
return rowIds.length > 0 || invalidParameters.length > 0
|
||||
? [
|
||||
{
|
||||
id: `${selectedNode.id}:${group.id}`,
|
||||
label: group.label,
|
||||
rowIds,
|
||||
defaultExpanded: group.defaultExpanded,
|
||||
errorCount: invalidParameters.length,
|
||||
hiddenErrorCount,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
})
|
||||
: [];
|
||||
|
||||
const simulationSettingErrors = simulationConfigValidationMessages(
|
||||
simulationConfig,
|
||||
@@ -5825,6 +5957,7 @@ function FlowWorkbench() {
|
||||
ariaLabel="组件参数"
|
||||
availableWidth={parameterTableAvailableWidth}
|
||||
columnLayout={parameterColumnLayout}
|
||||
groups={componentParameterGroups}
|
||||
onColumnLayoutChange={setParameterColumnLayout}
|
||||
rows={componentParameterRows}
|
||||
/>
|
||||
@@ -5929,6 +6062,7 @@ function buildProjectPayload(
|
||||
return {
|
||||
name: name.trim() || "untitled",
|
||||
mediumReferenceVersion: 1,
|
||||
amesimParameterEncodingVersion: 1,
|
||||
nodes: nodes.map((node) => ({
|
||||
id: node.id,
|
||||
type: "simulationComponent",
|
||||
@@ -5961,6 +6095,110 @@ function buildProjectPayload(
|
||||
};
|
||||
}
|
||||
|
||||
function numericChoiceValue(value: ParameterValue | undefined) {
|
||||
if (typeof value === "string" && value.trim() === "") {
|
||||
return null;
|
||||
}
|
||||
const numericValue = Number(value);
|
||||
return Number.isFinite(numericValue) ? numericValue : null;
|
||||
}
|
||||
|
||||
function parameterIsVisible(
|
||||
definition: ParameterDefinition,
|
||||
parameters: Record<string, ParameterValue>,
|
||||
) {
|
||||
return (
|
||||
!definition.visibleWhen?.length ||
|
||||
definition.visibleWhen.every((condition) => {
|
||||
const currentValue = numericChoiceValue(parameters[condition.parameter]);
|
||||
return currentValue !== null && condition.values.includes(currentValue);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeParameterGroups(
|
||||
value: unknown,
|
||||
parameterNames: ReadonlySet<string>,
|
||||
): ParameterGroupDefinition[] {
|
||||
if (!Array.isArray(value)) {
|
||||
return [];
|
||||
}
|
||||
const groupIds = new Set<string>();
|
||||
const groupedParameters = new Set<string>();
|
||||
const groups = value.flatMap((entry) => {
|
||||
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
||||
return [];
|
||||
}
|
||||
const candidate = entry as Record<string, unknown>;
|
||||
const id = typeof candidate.id === "string" ? candidate.id.trim() : "";
|
||||
const label =
|
||||
typeof candidate.label === "string" ? candidate.label.trim() : "";
|
||||
if (!id || !label || groupIds.has(id) || !Array.isArray(candidate.parameters)) {
|
||||
return [];
|
||||
}
|
||||
const parameters = candidate.parameters.flatMap((parameter) => {
|
||||
if (
|
||||
typeof parameter !== "string" ||
|
||||
!parameterNames.has(parameter) ||
|
||||
groupedParameters.has(parameter)
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
groupedParameters.add(parameter);
|
||||
return [parameter];
|
||||
});
|
||||
if (parameters.length === 0) {
|
||||
return [];
|
||||
}
|
||||
groupIds.add(id);
|
||||
const numericOrder = Number(candidate.order);
|
||||
return [
|
||||
{
|
||||
id,
|
||||
label,
|
||||
order: Number.isInteger(numericOrder) ? numericOrder : 0,
|
||||
parameters,
|
||||
defaultExpanded: candidate.defaultExpanded === true,
|
||||
},
|
||||
];
|
||||
});
|
||||
return groups.sort(
|
||||
(first, second) => first.order - second.order || first.id.localeCompare(second.id),
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeParameterVisibilityConditions(
|
||||
value: unknown,
|
||||
): ParameterVisibilityCondition[] | undefined {
|
||||
if (!Array.isArray(value)) {
|
||||
return undefined;
|
||||
}
|
||||
const conditions = value.flatMap((entry) => {
|
||||
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
||||
return [];
|
||||
}
|
||||
const candidate = entry as Record<string, unknown>;
|
||||
if (typeof candidate.parameter !== "string" || !candidate.parameter.trim()) {
|
||||
return [];
|
||||
}
|
||||
if (!Array.isArray(candidate.values)) {
|
||||
return [];
|
||||
}
|
||||
const values = [
|
||||
...new Set(
|
||||
candidate.values.flatMap((item) => {
|
||||
const numericValue = Number(item);
|
||||
return Number.isFinite(numericValue) ? [numericValue] : [];
|
||||
}),
|
||||
),
|
||||
];
|
||||
return values.length > 0
|
||||
? [{ parameter: candidate.parameter.trim(), values }]
|
||||
: [];
|
||||
});
|
||||
return conditions.length > 0 ? conditions : undefined;
|
||||
}
|
||||
|
||||
function normalizeParameterScientificNotation(
|
||||
value: unknown,
|
||||
): Record<string, ParameterScientificNotation> {
|
||||
@@ -5991,14 +6229,22 @@ function normalizeParameterScientificNotation(
|
||||
function normalizeLoadedNode(
|
||||
node: ProjectNodePayload,
|
||||
componentDefinitions: ComponentDefinition[],
|
||||
amesimParameterEncodingVersion?: 1 | null,
|
||||
): SimulationNode {
|
||||
const definition =
|
||||
componentDefinitions.find((item) => item.type === node.data.componentType) ??
|
||||
componentDefinitions.find((item) => item.modelType === node.data.modelType);
|
||||
const effectiveModelType =
|
||||
definition?.modelType || node.data.modelType || node.data.componentType;
|
||||
const rawParameters = node.data.parameters ?? {};
|
||||
const parameters = definition
|
||||
const mergedParameters = definition
|
||||
? { ...defaultParameters(definition), ...rawParameters }
|
||||
: { ...rawParameters };
|
||||
const parameters = migrateLegacyAmesimParameterEncoding(
|
||||
effectiveModelType,
|
||||
mergedParameters,
|
||||
amesimParameterEncodingVersion,
|
||||
);
|
||||
if (
|
||||
isAmesimGasMediumDefinition(definition) &&
|
||||
!Object.prototype.hasOwnProperty.call(rawParameters, "gi")
|
||||
@@ -6288,6 +6534,26 @@ function displayParameterValue(
|
||||
return formatEditableNumber(displayValue);
|
||||
}
|
||||
|
||||
function migrateLegacyAmesimParameterEncoding(
|
||||
modelType: string,
|
||||
parameters: Record<string, ParameterValue>,
|
||||
version?: 1 | null,
|
||||
) {
|
||||
if (version === 1 || modelType !== "amesim_mecmas21") {
|
||||
return { ...parameters };
|
||||
}
|
||||
const migrated = { ...parameters };
|
||||
(["useFriction", "strib"] as const).forEach((name) => {
|
||||
const value = numericChoiceValue(migrated[name]);
|
||||
if (value === 0) {
|
||||
migrated[name] = 1;
|
||||
} else if (value === 1) {
|
||||
migrated[name] = 2;
|
||||
}
|
||||
});
|
||||
return migrated;
|
||||
}
|
||||
|
||||
function formatEditableNumber(value: number) {
|
||||
if (!Number.isFinite(value)) {
|
||||
return "";
|
||||
@@ -6496,6 +6762,24 @@ function parameterValidationMessage(
|
||||
return "";
|
||||
}
|
||||
|
||||
function componentParameterValidationMessage(
|
||||
definition: ParameterDefinition,
|
||||
value: ParameterValue,
|
||||
selectedUnit: string,
|
||||
gasMediumOptions?: readonly AmesimGasMediumOption[],
|
||||
) {
|
||||
if (gasMediumOptions !== undefined) {
|
||||
const gasReferenceIndex = normalizeAmesimGasIndex(value);
|
||||
if (
|
||||
gasReferenceIndex === null ||
|
||||
!gasMediumOptions.some((option) => option.value === gasReferenceIndex)
|
||||
) {
|
||||
return "引用的介质定义不存在";
|
||||
}
|
||||
}
|
||||
return parameterValidationMessage(definition, value, selectedUnit);
|
||||
}
|
||||
|
||||
function simulationCalculatedValueMetadata(
|
||||
value: ParameterValue,
|
||||
unit: string,
|
||||
@@ -6951,7 +7235,11 @@ function parseProjectPayload(raw: string | null): ReactFlowProjectPayload | null
|
||||
!project.simulation ||
|
||||
typeof project.simulation !== "object" ||
|
||||
(project.mediumReferenceVersion !== undefined &&
|
||||
project.mediumReferenceVersion !== 1)
|
||||
project.mediumReferenceVersion !== null &&
|
||||
project.mediumReferenceVersion !== 1) ||
|
||||
(project.amesimParameterEncodingVersion !== undefined &&
|
||||
project.amesimParameterEncodingVersion !== null &&
|
||||
project.amesimParameterEncodingVersion !== 1)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
@@ -6987,6 +7275,7 @@ function buildSystemXml(
|
||||
system.setAttribute("name", project.name);
|
||||
system.setAttribute("schemaVersion", "2");
|
||||
system.setAttribute("mediumReferenceVersion", "1");
|
||||
system.setAttribute("amesimParameterEncodingVersion", "1");
|
||||
system.setAttribute("unitSystem", "SI");
|
||||
|
||||
const simulation = xmlDocument.createElement("Simulation");
|
||||
|
||||
Reference in new issue
Block a user