import i18n from "@/lang/index"; import { ApiError, ApiFieldError } from "@/utils/api-error"; /** * Локализация причины отказа. * * Ключ строится ИЗ КОДА, а не из текста ответа. Сервер присылает и своё * человекочитаемое сообщение — оно остаётся ответом для клиента без панели и * запасным вариантом здесь: код, которого панель ещё не знает, обязан доехать * до оператора хоть в каком-то виде, а не превратиться в пустую строку. * * Числа правил (границы длины, допустимые значения) приходят в `params`. * Второй копии этих чисел в панели нет намеренно: копия неизбежно разошлась бы * с серверной, и оператор читал бы «от 6 до 128», получая отказ по другим * границам. */ const t = i18n.global.t; const te = i18n.global.te; /** Локализованное название поля формы; при отсутствии — имя из ответа. */ function fieldLabel(field: string): string { const key = `error.field.${field}`; return te(key) ? t(key) : field; } /** Сообщение по одной причине отказа. */ export function describeFieldError(error: ApiFieldError): string { const key = `error.code.${error.code}`; if (te(key)) { return t(key, { field: error.field ? fieldLabel(error.field) : "", ...(error.params ?? {}), }); } return error.message; } /** Причины по именам полей формы — для подстановки в el-form. */ export function fieldErrorMap(error: ApiError): Record { const result: Record = {}; for (const item of error.fieldErrors()) { // Первая причина по полю выигрывает: показывать в одном поле две строки // некуда, а порядок ответа отражает порядок правил. if (item.field && !(item.field in result)) { result[item.field] = describeFieldError(item); } } return result; } /** * Одна строка, пригодная для тоста. * * Отказ уровня операции показывается как есть. Отказ по полям сворачивается в * перечисление «поле: причина» — тост при этом остаётся вторым сигналом, а * первым служит подсветка самих полей. */ export function describeApiError(error: ApiError): string { const operation = error.operationError(); if (operation) { return describeFieldError(operation); } const fields = error.fieldErrors(); if (fields.length > 0) { return fields .map((item) => `${fieldLabel(item.field!)}: ${describeFieldError(item)}`) .join("; "); } return error.message || t("common.systemError"); }