This commit is contained in:
che
2026-07-13 11:17:57 +05:00
parent e3490e5d2e
commit 6fff682f74
18 changed files with 411 additions and 453 deletions
+62 -56
View File
@@ -3,8 +3,6 @@ import type { Params, ControlCase, Analize, InitialCondition } from "@/models.ts
export const paramsApi = createModelApi<Params>("params");
export const controlCaseApi = createModelApi<ControlCase>("control_case");
export const analizeApi = createModelApi<Analize>("analize");
export const initialConditionApi = createModelApi<InitialCondition>("initial_condition");
export interface CsvChartResponse {
@@ -37,61 +35,53 @@ export interface InitialConditionResponse {
initial_condition: InitialCondition;
}
export async function getControlCaseChartData(id: number) {
const response = await apiClient.get<CsvChartResponse>(
`/control_case/${id}/chart-data`,
);
return response.data;
}
export async function getControlCasePsiSpectrum(id: number) {
const response = await apiClient.get<PsiSpectrumResponse>(
`/control_case/${id}/psi-spectrum`,
);
return response.data;
}
export async function getControlCaseFieldMap(id: number, time: number) {
const response = await apiClient.get<FieldMapResponse>(
`/control_case/${id}/field-map`,
{
params: { time },
},
);
return response.data;
}
export async function createControlCaseInitialCondition(id: number) {
const response = await apiClient.post<InitialConditionResponse>(
`/control_case/${id}/initial-condition`,
);
return response.data;
}
export interface LaunchControlCasePayload {
params_id: number;
name?: string;
}
export async function launchControlCase(payload: LaunchControlCasePayload) {
const response = await apiClient.post<ControlCase>(
"/control_case/launch",
payload,
);
return response.data;
}
export const controlCaseApi = {
...createModelApi<ControlCase>("control_case"),
export async function recalculateControlCaseAnalysis(id: number) {
const response = await apiClient.post<Analize>(
`/control_case/${id}/recalculate-analysis`,
);
return response.data;
}
async chartData(id: number) {
const response = await apiClient.get<CsvChartResponse>(
`/control_case/${id}/chart-data`,
);
return response.data;
},
export async function recalculateAnalize(id: number) {
const response = await apiClient.post<Analize>(`/analize/${id}/recalculate`);
return response.data;
}
async psiSpectrum(id: number) {
const response = await apiClient.get<PsiSpectrumResponse>(
`/control_case/${id}/psi-spectrum`,
);
return response.data;
},
async fieldMap(id: number, time: number) {
const response = await apiClient.get<FieldMapResponse>(
`/control_case/${id}/field-map`,
{
params: { time },
},
);
return response.data;
},
async createInitialCondition(id: number) {
const response = await apiClient.post<InitialConditionResponse>(
`/control_case/${id}/initial-condition`,
);
return response.data;
},
async launch(payload: LaunchControlCasePayload) {
const response = await apiClient.post<ControlCase>(
"/control_case/launch",
payload,
);
return response.data;
},
};
export interface AnalizeSeriesPoint {
case_id: number;
@@ -123,9 +113,25 @@ export interface AnalizeSeriesFilters {
group_parameter?: string;
}
export async function getAnalizeSeries(parameter: string, filters?: AnalizeSeriesFilters) {
const response = await apiClient.get<AnalizeSeriesResponse>("/analize/series", {
params: { parameter, ...(filters ?? {}) },
});
return response.data;
}
export const analizeApi = {
...createModelApi<Analize>("analize"),
async recalculate(id: number) {
const response = await apiClient.post<Analize>(`/analize/${id}/recalculate`);
return response.data;
},
async recalculateControlCase(id: number) {
const response = await apiClient.post<Analize>(
`/control_case/${id}/recalculate-analysis`,
);
return response.data;
},
async series(parameter: string, filters?: AnalizeSeriesFilters) {
const response = await apiClient.get<AnalizeSeriesResponse>("/analize/series", {
params: { parameter, ...(filters ?? {}) },
});
return response.data;
},
};
-1
View File
@@ -2,7 +2,6 @@ import axios from "axios";
export interface BaseEntity {
id?: number;
ID?: number;
}
export interface ListParams {
@@ -53,8 +53,8 @@ defineEmits<{
<label class="form-label">initial_condition</label>
<select v-model="form.initial_condition_id" class="form-select">
<option :value="null">Не задано</option>
<option v-for="condition in initialConditions" :key="condition.ID" :value="condition.ID">
{{ condition.name || `#${condition.ID}` }} {{ condition.file_path }}
<option v-for="condition in initialConditions" :key="condition.id" :value="condition.id">
{{ condition.name || `#${condition.id}` }} {{ condition.file_path }}
</option>
</select>
</div>
@@ -97,8 +97,8 @@ defineEmits<{
<td>
<select v-model="batchForm.fixed.initial_condition_id" class="form-select">
<option :value="null">Не задано</option>
<option v-for="condition in initialConditions" :key="condition.ID" :value="condition.ID">
{{ condition.name || `#${condition.ID}` }} {{ condition.file_path }}
<option v-for="condition in initialConditions" :key="condition.id" :value="condition.id">
{{ condition.name || `#${condition.id}` }} {{ condition.file_path }}
</option>
</select>
</td>
@@ -80,8 +80,8 @@ defineEmits<{
<td>
<select v-model="createForm.initial_condition_id" class="form-select form-select-sm">
<option :value="null"></option>
<option v-for="condition in initialConditions" :key="condition.ID" :value="condition.ID">
{{ condition.name || `#${condition.ID}` }}
<option v-for="condition in initialConditions" :key="condition.id" :value="condition.id">
{{ condition.name || `#${condition.id}` }}
</option>
</select>
</td>
+19 -19
View File
@@ -21,34 +21,34 @@ export interface Params {
}
export interface InitialCondition {
ID: number;
CreatedAt: string;
UpdatedAt: string;
DeletedAt: GormDeletedAt | null;
id: number;
created_at: string;
updated_at: string;
deleted_at: GormDeletedAt | null;
name: string;
file_path: string;
}
export interface ControlCase {
ID: number;
CreatedAt: string;
UpdatedAt: string;
DeletedAt: GormDeletedAt | null;
id: number;
created_at: string;
updated_at: string;
deleted_at: GormDeletedAt | null;
name: string;
paramsID: number;
params_id: number;
params: Params;
status: string;
}
export interface Analize {
ID: number;
CreatedAt: string;
UpdatedAt: string;
DeletedAt: GormDeletedAt | null;
Name: string;
CaseID: number;
CaseName: string;
PsiMax: number;
PsiLMax: number;
Omega: number;
id: number;
created_at: string;
updated_at: string;
deleted_at: GormDeletedAt | null;
name: string;
case_id: number;
case_name: string;
psi_max: number;
psi_l_max: number;
omega: number;
}
+6 -6
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { controlCaseApi, getAnalizeSeries, getControlCaseChartData, getControlCaseFieldMap, getControlCasePsiSpectrum } from '@/api.ts'
import { analizeApi, controlCaseApi } from '@/api.ts'
import { formatApiError } from '@/api_client.ts'
import type { ControlCase } from '@/models.ts'
import { controlCaseStatusMeta } from '@/statuses.ts'
@@ -446,7 +446,7 @@ async function loadData() {
error.value = ''
try {
const response = await getAnalizeSeries(selectedParameter.value, {
const response = await analizeApi.series(selectedParameter.value, {
group_parameter: groupParameter.value || undefined,
filter_parameter: filterParameter.value || undefined,
filter_min: filterMin.value === '' ? undefined : Number(filterMin.value),
@@ -498,8 +498,8 @@ async function loadSelectedCase(caseId: number) {
try {
const [caseData, csvData, spectrumData] = await Promise.all([
controlCaseApi.retrieve(caseId),
getControlCaseChartData(caseId),
getControlCasePsiSpectrum(caseId),
controlCaseApi.chartData(caseId),
controlCaseApi.psiSpectrum(caseId),
])
selectedCase.value = caseData
@@ -543,7 +543,7 @@ async function loadFieldMap(time: number) {
selectedFieldMapError.value = ''
try {
selectedFieldMap.value = await getControlCaseFieldMap(selectedCaseId.value, time)
selectedFieldMap.value = await controlCaseApi.fieldMap(selectedCaseId.value, time)
renderFieldMap()
} catch (err) {
selectedFieldMapError.value = formatApiError(err, 'Не удалось загрузить карту полей.')
@@ -711,7 +711,7 @@ onBeforeUnmount(() => {
</div>
<div class="col-12 col-lg-4">
<div class="text-muted small">Params ID</div>
<div class="fw-semibold">{{ selectedCase.paramsID }}</div>
<div class="fw-semibold">{{ selectedCase.params_id }}</div>
</div>
</div>
+26 -26
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { RouterLink } from 'vue-router'
import { analizeApi, recalculateAnalize } from '@/api.ts'
import { analizeApi } from '@/api.ts'
import { formatApiError, isPaginatedResponse } from '@/api_client.ts'
import type { Analize } from '@/models.ts'
@@ -30,16 +30,16 @@ const pageEnd = computed(() => {
function normalizeAnalize(item: Analize | Record<string, unknown>): Analize {
const record = item as Record<string, unknown>
return {
ID: Number(record.ID ?? record.id ?? 0),
CreatedAt: String(record.CreatedAt ?? record.createdAt ?? ''),
UpdatedAt: String(record.UpdatedAt ?? record.updatedAt ?? ''),
DeletedAt: (record.DeletedAt ?? record.deletedAt ?? null) as Analize['DeletedAt'],
Name: String(record.Name ?? record.name ?? ''),
CaseID: Number(record.CaseID ?? record.case_id ?? 0),
CaseName: String(record.CaseName ?? record.case_name ?? ''),
PsiMax: Number(record.PsiMax ?? record.psi_max ?? 0),
PsiLMax: Number(record.PsiLMax ?? record.psi_l_max ?? 0),
Omega: Number(record.Omega ?? record.omega ?? 0),
id: Number(record.id ?? 0),
created_at: String(record.created_at ?? ''),
updated_at: String(record.updated_at ?? ''),
deleted_at: (record.deleted_at ?? null) as Analize['deleted_at'],
name: String(record.name ?? ''),
case_id: Number(record.case_id ?? 0),
case_name: String(record.case_name ?? ''),
psi_max: Number(record.psi_max ?? 0),
psi_l_max: Number(record.psi_l_max ?? 0),
omega: Number(record.omega ?? 0),
}
}
@@ -81,13 +81,13 @@ async function loadItems() {
}
async function recalculate(item: Analize) {
recalculatingId.value = item.ID
recalculatingId.value = item.id
error.value = ''
try {
const updated = await recalculateAnalize(item.ID)
const updated = await analizeApi.recalculate(item.id)
const normalized = normalizeAnalize(updated)
items.value = items.value.map((current) => (current.ID === normalized.ID ? normalized : current))
items.value = items.value.map((current) => (current.id === normalized.id ? normalized : current))
} catch (err) {
error.value = formatApiError(err, 'Не удалось пересчитать analize.')
} finally {
@@ -134,32 +134,32 @@ onMounted(loadItems)
<tr v-if="items.length === 0">
<td colspan="8" class="text-center text-muted py-4">Записи не найдены</td>
</tr>
<tr v-for="item in items" :key="item.ID">
<td class="fw-semibold">{{ item.ID }}</td>
<td>{{ item.Name || '—' }}</td>
<tr v-for="item in items" :key="item.id">
<td class="fw-semibold">{{ item.id }}</td>
<td>{{ item.name || '—' }}</td>
<td>
<div class="d-flex flex-column">
<RouterLink
class="fw-medium text-decoration-none"
:to="{ name: 'control-case-detail', params: { id: item.CaseID } }"
:to="{ name: 'control-case-detail', params: { id: item.case_id } }"
>
{{ item.CaseName || '—' }}
{{ item.case_name || '—' }}
</RouterLink>
<small class="text-muted">#{{ item.CaseID }}</small>
<small class="text-muted">#{{ item.case_id }}</small>
</div>
</td>
<td>{{ item.PsiMax }}</td>
<td>{{ item.PsiLMax }}</td>
<td>{{ item.Omega }}</td>
<td>{{ formatDate(item.CreatedAt) }}</td>
<td>{{ item.psi_max }}</td>
<td>{{ item.psi_l_max }}</td>
<td>{{ item.omega }}</td>
<td>{{ formatDate(item.created_at) }}</td>
<td class="text-end">
<button
class="btn btn-sm btn-outline-primary"
type="button"
@click="recalculate(item)"
:disabled="recalculatingId === item.ID"
:disabled="recalculatingId === item.id"
>
{{ recalculatingId === item.ID ? 'Пересчет...' : 'Пересчитать' }}
{{ recalculatingId === item.id ? 'Пересчет...' : 'Пересчитать' }}
</button>
</td>
</tr>
@@ -2,7 +2,7 @@
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { RouterLink, useRoute } from 'vue-router'
import * as echarts from 'echarts'
import { getControlCaseChartData, type CsvChartResponse } from '@/api.ts'
import { controlCaseApi, type CsvChartResponse } from '@/api.ts'
import { formatApiError } from '@/api_client.ts'
const route = useRoute()
@@ -61,7 +61,7 @@ async function loadData() {
error.value = ''
try {
data.value = await getControlCaseChartData(id.value)
data.value = await controlCaseApi.chartData(id.value)
renderChart()
} catch (err) {
error.value = formatApiError(err, 'Не удалось загрузить данные графика.')
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { RouterLink, useRoute } from 'vue-router'
import { controlCaseApi, recalculateControlCaseAnalysis, createControlCaseInitialCondition } from '@/api.ts'
import { analizeApi, controlCaseApi } from '@/api.ts'
import { formatApiError } from '@/api_client.ts'
import type { ControlCase } from '@/models.ts'
import { controlCaseStatusMeta } from '@/statuses.ts'
@@ -66,7 +66,7 @@ async function recalculateAnalysis() {
statusMessage.value = ''
try {
await recalculateControlCaseAnalysis(id.value)
await analizeApi.recalculateControlCase(id.value)
statusMessage.value = 'Анализ пересчитан.'
} catch (err) {
error.value = formatApiError(err, 'Не удалось пересчитать анализ.')
@@ -83,7 +83,7 @@ async function createInitialCondition() {
statusMessage.value = ''
try {
const response = await createControlCaseInitialCondition(id.value)
const response = await controlCaseApi.createInitialCondition(id.value)
statusMessage.value = `Начальные условия созданы: ${response.initial_condition.file_path}`
} catch (err) {
error.value = formatApiError(err, 'Не удалось создать начальные условия.')
@@ -153,19 +153,19 @@ watch(id, loadItem)
<div class="card-body">
<dl class="row mb-0">
<dt class="col-sm-3">ID</dt>
<dd class="col-sm-9">{{ item.ID }}</dd>
<dd class="col-sm-9">{{ item.id }}</dd>
<dt class="col-sm-3">Params ID</dt>
<dd class="col-sm-9">{{ item.paramsID }}</dd>
<dd class="col-sm-9">{{ item.params_id }}</dd>
<dt class="col-sm-3">Создан</dt>
<dd class="col-sm-9">{{ formatDate(item.CreatedAt) }}</dd>
<dd class="col-sm-9">{{ formatDate(item.created_at) }}</dd>
<dt class="col-sm-3">Обновлён</dt>
<dd class="col-sm-9">{{ formatDate(item.UpdatedAt) }}</dd>
<dd class="col-sm-9">{{ formatDate(item.updated_at) }}</dd>
<dt class="col-sm-3">Удалён</dt>
<dd class="col-sm-9">{{ formatValue(item.DeletedAt) }}</dd>
<dd class="col-sm-9">{{ formatValue(item.deleted_at) }}</dd>
</dl>
</div>
</div>
+5 -5
View File
@@ -112,8 +112,8 @@ onMounted(loadItems);
Записи не найдены
</td>
</tr>
<tr v-for="item in items" :key="item.ID">
<td class="fw-semibold">{{ item.ID }}</td>
<tr v-for="item in items" :key="item.id">
<td class="fw-semibold">{{ item.id }}</td>
<td>{{ item.name || "—" }}</td>
<td>
<span
@@ -123,14 +123,14 @@ onMounted(loadItems);
{{ controlCaseStatusMeta(item.status).label }}
</span>
</td>
<td>{{ item.paramsID }}</td>
<td>{{ formatDate(item.CreatedAt) }}</td>
<td>{{ item.params_id }}</td>
<td>{{ formatDate(item.created_at) }}</td>
<td class="text-end">
<RouterLink
class="btn btn-sm btn-primary"
:to="{
name: 'control-case-detail',
params: { id: item.ID },
params: { id: item.id },
}"
>
Открыть
+4 -4
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { initialConditionApi, launchControlCase, paramsApi } from "@/api.ts";
import { controlCaseApi, initialConditionApi, paramsApi } from "@/api.ts";
import { formatApiError, isPaginatedResponse } from "@/api_client.ts";
import ParamsEditCard from "@/components/params/ParamsEditCard.vue";
import ParamsQuickBatchCard from "@/components/params/ParamsQuickBatchCard.vue";
@@ -304,7 +304,7 @@ async function createBatch() {
payload[batchForm.variable] = value;
const created = await paramsApi.create(payload as never);
await launchControlCase({
await controlCaseApi.launch({
params_id: created.id,
name: `${batchForm.variable}-${value}`,
});
@@ -324,11 +324,11 @@ async function launchParams(item: Params) {
error.value = "";
try {
const controlCase = await launchControlCase({
const controlCase = await controlCaseApi.launch({
params_id: item.id,
name: `case-${item.id}`,
});
await router.push({ name: "control-case-detail", params: { id: controlCase.ID } });
await router.push({ name: "control-case-detail", params: { id: controlCase.id } });
} catch (err) {
error.value = formatApiError(err, "Не удалось запустить расчет.");
} finally {