docs: 更新文档

This commit is contained in:
R524809
2026-09-20 15:23:44 +08:00
parent 880e441bc6
commit e0e07be4ea
19 changed files with 164 additions and 312 deletions
@@ -431,9 +431,11 @@ if missing:
## 7. 缓存策略
Ozon 只定义查询参数和分页规则,不规定 Atlas 的 TTL。2026-09-18 的[架构决策](../../architecture/platform-product-reference-catalog.md)将属性定义和字典候选值设为平台级参考数据:同一平台所有门店共用,本阶段不维护门店差异层;此方案尚未实现。当前代码仍以门店、类目和类型为作用域按需同步,用户从 Atlas 本地缓存读取。
Ozon 只定义查询参数和分页规则,不规定 Atlas 的 TTL。Atlas 已按 2026-09-18 的[架构决策](../../architecture/platform-product-reference-catalog.md)将属性定义和字典候选值迁移为平台级参考数据:同一平台所有门店共用,本阶段不维护门店差异层。商品编辑器、草稿校验和发布预检都从 Atlas 平台缓存读取,Ozon 请求统一由 Worker 使用平台参考源凭据执行。
目标同步方式:对活跃 `description_category_id + type_id` 的属性定义定期后台复核;字典候选值至少以类目、类型、属性、字典 ID 和语言限定作用域。`category_dependent=false` 可以作为进一步去重的依据,但在跨账号/跨类目验证前不能只以 `dictionary_id` 合并。小字典可完整分页并标记 `complete`;大字典先保存常用页与搜索命中,并明确标记 `partial`。搜索结果不是全集,不能据此清理未命中的旧值。定时和管理员手动同步必须共用异步任务链路,成功后原子切换版本,失败保留上次成功值。
类型属性和字典默认 14 天内 fresh,14~21 天(含 21 天)stale 时旧缓存可用并低优先级刷新,严格超过 21 天或从未同步时必须高优先级刷新成功后才能作为当前 schema、候选值或发布依据。系统不周期性扫描属性和字典;刷新由管理员批次/单字典操作、普通用户访问或发布预检触发。
字典候选值至少以平台、类目类型、Atlas 属性 UUID、外部值 ID 和语言限定作用域。`category_dependent=false` 可以作为进一步去重的依据,但在跨账号/跨类目验证前不能只以 `dictionary_id` 合并。小字典可完整分页并标记 `complete`;大字典保存已同步页与搜索命中并明确标记 `partial`。搜索结果不是全集,不能据此清理未命中的旧值;partial 字典的规范化关键词有独立缓存状态。成功后原子更新缓存,失败保留上次成功值。
---
@@ -510,106 +512,13 @@ Ozon 只定义查询参数和分页规则,不规定 Atlas 的 TTL。2026-09-18
---
## 10. V2 项目集成
## 10. Atlas 当前集成
### API 层(已实现)
```python
# server/api/categories.py
@router.get("/categories/{category_id}/attributes")
async def get_attributes(
category_id: int,
type_id: int = Query(...),
shop_id: str = Query(...),
db: AsyncSession = Depends(get_db)
):
shop = await get_shop(db, shop_id)
attrs = await ozon_client.get_category_attributes(
shop.client_id_dec,
shop.api_key_dec,
category_id,
type_id
)
return {"result": attrs}
@router.get("/categories/attribute/{attribute_id}/values")
async def get_attribute_values(
attribute_id: int,
category_id: int = Query(...),
type_id: int = Query(...),
q: str = Query(None), # 搜索关键词
shop_id: str = Query(...),
db: AsyncSession = Depends(get_db)
):
shop = await get_shop(db, shop_id)
if q and len(q) >= 2:
# 搜索接口
values = await ozon_client.search_attribute_values(
shop.client_id_dec, shop.api_key_dec,
attribute_id, category_id, type_id, q
)
else:
# 全量拉取(分页)
values = await ozon_client.get_attribute_values(
shop.client_id_dec, shop.api_key_dec,
attribute_id, category_id, type_id
)
return {"result": values}
```
### 前端(待实现)
```tsx
// studio/src/pages/product/components/AttributeMapper.tsx
import { Form, Select, Input, Tag } from 'antd';
export function AttributeMapper({ categoryId, typeId, rawParams, onChange }) {
const [attributes, setAttributes] = useState([]);
useEffect(() => {
fetch(`/api/categories/${categoryId}/attributes?type_id=${typeId}`)
.then(r => r.json())
.then(data => setAttributes(data.result));
}, [categoryId, typeId]);
// 自动匹配
const autoMatch = () => {
const matched = rawParams.map(p => {
const attr = attributes.find(a =>
normalize(a.name) === normalize(p.key)
);
return attr ? { ...p, attrId: attr.id, attr } : p;
});
return matched;
};
return (
<div>
{autoMatch().map((item, i) => (
<Form.Item
key={i}
label={item.key}
required={item.attr?.is_required}
>
{item.attr?.dictionary_id > 0 ? (
<Select
showSearch
placeholder="选择字典值"
onSearch={(q) => fetchValues(item.attr.id, q)}
/>
) : (
<Input defaultValue={item.value} />
)}
</Form.Item>
))}
</div>
);
}
```
- 商品编辑器通过 `GET /api/product-platform-profiles/{profile_id}/attribute-schema` 读取当前平台类型属性,响应包含 Atlas `attribute_id` 和统一 `cache` 元数据。
- 字典通过 `GET /api/product-platform-profiles/{profile_id}/attribute-dictionaries/{attribute_id}` 读取;`attribute_id` 是平台属性 UUID,不以门店或单独 `dictionary_id` 定位。
- fresh/stale 立即返回;expired/missing 创建或复用高优先级任务并最多等待 5 秒,仍未完成时返回 `202`。浏览器不会拿到平台凭据或未落库的 Ozon 临时结果。
- 发布前使用 `POST /api/product-platform-profiles/{profile_id}/publish-preflights`,只刷新当前类型 schema 和所选 SKU 实际使用的字典,再执行必填、scope、字典有效性及其他首次上架校验。
- 管理后台支持三种类型属性批次、单字典同步、缓存策略弹窗和最近任务观察;类目树固定每 7 天同步,属性与字典不做周期性全量扫描。
---
@@ -617,5 +526,5 @@ export function AttributeMapper({ categoryId, typeId, rawParams, onChange }) {
- [02-category-tree.md](./02-category-tree.md) —— 获取类目树
- [04-product-import.md](./04-product-import.md) —— 发布商品(使用属性)
- [docs/v2/database.md](../v2/database.md) §2.7 —— 属性缓存表结构
- [docs/v2/ozon-publish.md](../v2/ozon-publish.md) §3 —— 属性映射策略
- [平台目录缓存刷新方案](../../architecture/platform-catalog-cache-refresh-plan.md) —— 属性和字典缓存状态机
- [商品编辑与发布 API](../../api/product-editor-and-publishing.md) —— 当前 Atlas 端点与发布预检