import 'package:patbond_flutter/core/network/api_exception.dart'; /// 资料页/编辑页的错误文案映射(沿 `petLoadErrorMessage` 先例: /// 服务端原始 message 一律不上屏)。 String profileLoadErrorMessage(ApiException? error) => switch (error) { ApiNetworkException _ => '网络异常,请检查网络后重试', ApiRateLimitException _ => '请求过于频繁,请稍后再试', _ => '加载失败,请稍后重试', }; /// 保存资料的失败文案,按契约 v1.4.0 的 `PATCH /api/v1/me` 错误谱分层: /// /// | 码 | 成因 | 文案取向 | /// | --- | --- | --- | /// | 40000 | 昵称长度/纯空白、空 patch、非法 UUID | 指向输入本身可改 | /// | 40405 | 头像 asset 不存在/非本人/已删/用途不符 | 引导重新上传 | /// | 42203 | 本人头像 asset 仍在 uploading/failed | 明说「还没传完」,可重试 | /// /// 40000 的三种成因在客户端已各自前置拦截(长度校验 / 空 patch 短路 / /// assetId 来自服务端),真收到 40000 说明校验与服务端有偏差, /// 故文案不写死「昵称」,只指向「填写内容」。 String profileSaveErrorMessage(ApiException? error) => switch (error) { ApiBusinessException(code: ApiCodes.paramError) => '填写内容不符合要求,请检查后重试', ApiBusinessException(code: ApiCodes.mediaNotFound) => '头像已失效,请重新上传', ApiBusinessException(code: ApiCodes.mediaNotReady) => '头像还没上传完,请稍后重试', ApiNetworkException _ => '网络异常,请检查网络后重试', ApiRateLimitException _ => '请求过于频繁,请稍后再试', _ => '保存失败,请稍后重试', }; /// 昵称的客户端校验,与后端 `ck_users_nickname`(btrim + 1~32)对齐。 /// /// **长度按码点计**(`String.characters` 的等价物 `runes`):数据库 /// `char_length` 数的是码点,若按 UTF-16 `String.length` 校验,32 个 emoji /// 的合法昵称(UTF-16 长度 64)会被客户端误拒。 /// /// 返回 null 即通过;非空即字段级 errorText。 String? validateNickname(String raw) { // btrim 对齐:服务端先 btrim 再判长度,故校验也先 trim。 final trimmed = raw.trim(); if (trimmed.isEmpty) { // 纯空白是 400/40000 而非隐式清空——清空走「清除昵称」显式入口。 return '昵称不能为空,如需清除请用下方「清除昵称」'; } if (trimmed.runes.length > 32) return '昵称最多 32 个字'; return null; }