feat(web): 店铺管理页与页头平台选择器接入真实 API

- 页头平台选择器:PlatformProvider 加载平台目录与平台上下文
  (X-Atlas-Platform-Id header),平台 id 仅作为非敏感 UI 偏好存
  localStorage,默认取目录第一家(Ozon 优先)
- 店铺管理页覆盖 docs/api/stores-and-platforms.md 已实现接口:
  游标分页列表、创建(202+operation)、编辑(If-Match 乐观锁、
  409 刷新提示)、设为默认、重新验证凭据、仓库同步(422 脱敏
  错误展示)、软删除(DEFAULT_STORE_REPLACEMENT_REQUIRED 提示)
- services/api.ts 新增 getList(保留 {data, meta} 分页信封)与
  apiErrorCode;services/stores.ts 按契约生成 Idempotency-Key
- @atlas/contracts 补充只读响应类型 Platform / PlatformContext /
  CursorPaginationMeta / StoreOperationResponse(无行为变更)
- API Key 仅存在于提交瞬间的内存表单,不落任何存储
- 浏览器实测:注册→平台切换→创建/编辑/设默认/删除保护/同步
  错误路径→刷新会话恢复全部通过;typecheck + production build 通过
This commit is contained in:
2026-09-03 21:40:02 +08:00
parent 8655b7805f
commit 446baf5939
11 changed files with 991 additions and 9 deletions
+2
View File
@@ -10,6 +10,7 @@ import {
UserOutlined,
} from '@ant-design/icons';
import SidebarMenu from './SidebarMenu';
import PlatformSelector from './PlatformSelector';
import { getBreadcrumbItems } from './menuConfig';
import { useSession } from '@/services/session';
import './MainLayout.css';
@@ -156,6 +157,7 @@ const MainLayout = () => {
</div>
{session && (
<div className="header-right">
<PlatformSelector />
<Dropdown
menu={{ items: userMenuItems, onClick: handleUserMenuClick }}
trigger={['hover']}