内容管理
概述
内容管理专注于对单个内容库的数据管理,可以理解为类似在线表格的数据表格维护,主要涉及对于大量数据的展示、编辑、查询、过滤、排序、等操作。以及灵活的筛选构建器。
行的状态
- New 初次导入
- Outdated Key不变,但是内容有更新
- Partial Completed 部分目标语有翻译
- Completed 所有目标语都有翻译
当订单交付时,判断一下当前行的所有译文是否都被填充,如果是则标记为Completed,否则标记为Partial Completed,然后状态允许用户手动改成自己希望的状态,当用户修改原文时,如果是Completed或者Partial Completed,则状态变为Outdated。
查询构建器
查询构建器可以创建一个保存在数据表中的可复用的查询条件,一组查询条件可以针对不同字段制定不同的查询条件,如包含,不包含,等于,不等于,大于,小于,大于等于,小于等于,范围等。
字段与条件
下表列出了内容管理系统中各字段支持的查询条件:
| 字段 | 支持的条件 |
|---|---|
| Key | 等于、包含、开头为 |
| Status | 在选项中 |
| Source | 等于、包含 |
| Target (所有语言) | 等于、包含、是否为空 |
| CreatedAt | 大于、小于、大于等于、小于等于、范围 |
| UpdatedAt | 大于、小于、大于等于、小于等于、范围 |
| Locked | 是否锁定 |
| Color | 颜色选择器(在选项中) |
标签规则(Tag Rules)
标签规则是指一组正则表达式,用于锁定原文中需要保护的部分,被保护的部分不需要翻译,不参与报价。标签规则是和Repository关联的,标签规则可以在多个Repository中共享,也就是说查询构建器,当一个人创建的时候如果选择私有,则仅仅自己可以应用,但是锁定器是直接应用在Repository上的,一旦应用对所有用户可见,系统会内置一些常用的锁定器,如:HTML标签等。Workspace管理员可以管理Workspace中的锁定器。
查询构建器和标签规则的共享范围
工作空间内共享,创建者可删除。
内容快照
内容快照是指当创建订单时,根据当时内容库的状态,记录下来的一系列信息,通过这些信息可以确定订单要执行本地化的唯一内容,一个快照记录的快照信息包括:
- 内容库的ID
- 当前客户浏览的 Content Version
- 当前的筛选条件
- 当前的标签规则(Tag Rules)
以上信息构成一条快照记录,一条快照记录一定可以确定一个唯一的,在订单生命周期内不会变的内容,其中筛选条件和标签规则记录的是当时的实际内容不会是ID,不与外部表关联,为了溯源等需求,并且快照也是订单的一部分,所以快照信息不需要删除,应该长期保存。
版本行为
版本创建
以下行为会使内容库产生新的版本
- 触发导入数据时
- 订单回更目标语翻译时
版本回滚
- 通过版本回滚可以实现导入行为的撤销
- 订单预览,如果当用户没有确认验收订单时,预览的是一个临时版本,这个版本可以被撤销
锁定行为
- 当有活动中的订单时,意味着内容库订单的原文回更的译文必须与当前版本锁定,如果此时再次导入,版本加一,会造成版本冲突,所以在有订单的前提下,锁定库不允许导入,对应到实际的实现中,无论是Excel还是UE应该有Pending状态的任务,当订单交付时,应该检查Pending状态的任务使其开始,反过来如果有正在In Progress的任务,也不能创建订单。
- 未来改进,未来目标实现可以并行的导入和订单生产,那种情形下,需要有原始版本和订单版本的对应关系,相当于订单的版本是一个导入版本的子版本,或者引入分支概念。
关联的外部系统
暂无
接口设计
1. 内容列表查询接口
- 说明:获取内容库中的数据列表,支持分页、排序和过滤
- 方法:GET
- URL:/api/v1/repositories/{repositoryId}/contents
- 请求参数:json
{ "page": 1, "page_size": 20, "sort": [ { "field": "created_at", "order": "desc" } ], "filters": [ { "field": "status", "operator": "in", "value": ["new", "updated"] } ], "query_builder_id": "query_builder_uuid", "search": "welcome" } - 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "total": 100, "items": [ { "id": "content_uuid", "content_key": "app/welcome/title", "source": { "text": "Welcome to our app", "language": "en-US" }, "translations": [ { "language": "zh-CN", "text": "欢迎使用我们的应用", "status": "translated" } ], "status": "new", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] } }
2. 内容详情查询接口
- 说明:获取单个内容的详细信息
- 方法:GET
- URL:/api/v1/repositories/{repositoryId}/contents/
- 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "id": "content_uuid", "content_key": "app/welcome/title", "source": { "text": "Welcome to our app", "language": "en-US" }, "translations": [ { "language": "zh-CN", "text": "欢迎使用我们的应用", "status": "translated", "updated_at": "2024-01-01T00:00:00Z", "updated_by": "user_id" } ], "metadata": { "source_type": "local_file", "source_info": { "data_source_id": "uuid", "file_id": "uuid", "sheet_name": "Sheet1", "row_number": 1 } }, "status": "new", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "created_by": "user_id", "updated_by": "user_id" } }
3. 内容更新接口
- 说明:更新内容的翻译或元数据信息
- 方法:PATCH
- URL:/api/v1/repositories/{repositoryId}/contents/
- 请求示例:json
{ "translations": [ { "language": "zh-CN", "text": "欢迎使用我们的应用", "status": "translated" } ], "metadata": { "tags": ["homepage", "welcome"] } } - 响应示例:json
{ "code": 200, "message": "更新成功", "data": { "id": "content_uuid", "updated_at": "2024-01-01T00:00:00Z" } }
4. 内容批量更新接口
- 说明:批量更新多个内容的翻译或元数据信息
- 方法:PATCH
- URL:/api/v1/repositories/{repositoryId}/contents/batch
- 请求示例:json
{ "items": [ { "id": "content_uuid_1", "translations": [ { "language": "zh-CN", "text": "欢迎", "status": "translated" } ] }, { "id": "content_uuid_2", "translations": [ { "language": "zh-CN", "text": "再见", "status": "translated" } ] } ] } - 响应示例:json
{ "code": 200, "message": "批量更新成功", "data": { "success_count": 2, "failed_count": 0, "failed_items": [] } }
5. 内容历史记录查询接口
- 说明:查询内容的历史变更记录
- 方法:GET
- URL:/api/v1/repositories/{repositoryId}/contents/{contentId}/history
- 请求参数:json
{ "page": 1, "page_size": 20 } - 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "total": 5, "items": [ { "id": "history_uuid", "type": "translation_update", "changes": { "before": { "text": "旧的翻译", "status": "draft" }, "after": { "text": "新的翻译", "status": "translated" } }, "action": "user_edit", "created_at": "2024-01-01T00:00:00Z", "created_by": "user_id" } ] } }
6. 内容导出接口
- 说明:导出内容库中的数据为指定格式
- 方法:POST
- URL:/api/v1/repositories/{repositoryId}/contents/export
- 请求示例:json
{ "format": "excel", "filters": [ { "field": "status", "operator": "in", "value": ["new", "updated"] } ], "languages": ["en-US", "zh-CN"], "columns": ["content_key", "source", "translations"] } - 响应示例:json
{ "code": 200, "message": "导出任务已创建", "data": { "task_id": "task_uuid", "status": "processing" } }
7. 内容导出状态查询接口
- 说明:查询内容导出任务的状态
- 方法:GET
- URL:/api/v1/repositories/{repositoryId}/contents/export/
- 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "task_id": "task_uuid", "status": "completed", "progress": 100, "file_url": "https://example.com/download/export.xlsx", "created_at": "2024-01-01T00:00:00Z", "completed_at": "2024-01-01T00:01:00Z" } }
8. 内容筛选条件查询接口
- 说明:获取可用的筛选条件配置
- 方法:GET
- URL:/api/v1/repositories/{repositoryId}/contents/filters
- 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "filters": [ { "field": "status", "label": "状态", "type": "enum", "options": [ {"value": "new", "label": "新建"}, {"value": "updated", "label": "已更新"}, {"value": "deleted", "label": "已删除"} ] }, { "field": "created_at", "label": "创建时间", "type": "datetime" } ] } }
10. 创建查询构建器接口
- 说明:创建一个新的查询构建器配置
- 方法:POST
- URL:/api/v1/repositories/{repositoryId}/query-builders
- 请求示例:json
{ "name": "待本地化", "description": "查询所有需要本地化的内容", "conditions": [ { "field": "status", "operator": "in", "value": ["new", "update"] }, { "field": "created_at", "operator": "range", "value": { "start": "2024-01-01T00:00:00Z", "end": "2024-12-31T23:59:59Z" } } ], "is_public": true, // 是否公开(其他人可用) "is_shared": true // 是否跨Repository共用 } - 响应示例:json
{ "code": 200, "message": "创建成功", "data": { "id": "query_builder_uuid", "created_at": "2024-01-01T00:00:00Z" } }
11. 更新查询构建器接口
- 说明:更新现有的查询构建器配置
- 方法:PUT
- URL:/api/v1/repositories/{repositoryId}/query-builders/
- 请求示例:json
{ "name": "待本地化", "description": "查询所有需要本地化的内容", "conditions": [ { "field": "status", "operator": "in", "value": ["update"] } ], "is_public": true, "is_shared": true } - 响应示例:json
{ "code": 200, "message": "更新成功", "data": { "id": "query_builder_uuid", "updated_at": "2024-01-01T00:00:00Z" } }
12. 删除查询构建器接口
- 说明:删除指定的查询构建器配置
- 方法:DELETE
- URL:/api/v1/repositories/{repositoryId}/query-builders/
- 响应示例:json
{ "code": 200, "message": "删除成功" }
13. 查询构建器详情接口
- 说明:获取单个查询构建器的详细配置
- 方法:GET
- URL:/api/v1/repositories/{repositoryId}/query-builders/
- 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "id": "query_builder_uuid", "name": "未翻译内容查询", "description": "查询所有未翻译的中文内容", "conditions": [ { "field": "translations.zh-CN.status", "operator": "in", "value": ["untranslated", "draft"] } ], "is_shared": true, "is_public": true, "created_by": "user_id", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } }
16. 内容版本列表查询接口
- 说明:获取一个或多个内容的历史版本,支持批量查询
- 方法:POST
- URL:/api/v1/repositories/{repositoryId}/contents/versions/list
- 请求参数:json
{ "content_ids": ["content_uuid_1", "content_uuid_2"], "page": 1, "page_size": 20 } - 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "items": [ { "content_id": "content_uuid_1", "current_version": 3, "versions": [ { "id": "version_uuid", "version": 3, "content": { "source": { "text": "Welcome to our app", "language": "en-US" }, "translations": [ { "language": "zh-CN", "text": "欢迎使用我们的应用", "status": "translated" } ] }, "metadata": { "source_type": "local_file", "source_info": { "data_source_id": "uuid", "file_id": "uuid", "sheet_name": "Sheet1", "row_number": 1 } }, "created_by": "user_id", "created_at": "2024-01-01T00:00:00Z", "comment": "更新中文翻译" } ] }, { "content_id": "content_uuid_2", "current_version": 2, "versions": [ { "id": "version_uuid_2", "version": 2, "content": { "source": { "text": "Goodbye", "language": "en-US" }, "translations": [ { "language": "zh-CN", "text": "再见", "status": "translated" } ] }, "created_by": "user_id", "created_at": "2024-01-01T00:00:00Z", "comment": "初始翻译" } ] } ] } }
17. 内容版本回滚接口
- 说明:将一个或多个内容回滚到指定的历史版本
- 方法:POST
- URL:/api/v1/repositories/{repositoryId}/contents/versions/rollback
- 请求示例:json
{ "items": [ { "content_id": "content_uuid_1", "version_id": "version_uuid_1" } ], "comment": "回滚到修改前的版本" } - 响应示例:json
{ "code": 200, "message": "回滚成功", "data": { "success_count": 1, "failed_count": 0, "failed_items": [], "results": [ { "content_id": "content_uuid_1", "new_version": 4, "status": "success", "updated_at": "2024-01-01T00:00:00Z" } ] } }
18. 标签规则列表查询接口
- 说明:获取可用的标签规则列表
- 方法:GET
- URL:/api/v1/workspaces/{workspaceId}/content-lockers
- 请求参数:json
{ "page": 1, "page_size": 20 } - 响应示例:json
{ "code": 200, "message": "查询成功", "data": { "total": 10, "items": [ { "id": "locker_uuid", "name": "HTML标签锁定器", "description": "锁定HTML标签,防止翻译破坏标签结构", "patterns": [ "<[^>]+>", "\\{\\{[^}]+\\}\\}" ], "type": "system", "created_by": "system", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] } }
19. 创建标签规则接口
- 说明:创建新的标签规则
- 方法:POST
- URL:/api/v1/workspaces/{workspaceId}/content-lockers
- 请求示例:json
{ "name": "变量锁定器", "description": "锁定代码中的变量引用", "patterns": [ "\\$\\{[^}]+\\}", "\\%\\{[^}]+\\}" ] } - 响应示例:json
{ "code": 200, "message": "创建成功", "data": { "id": "locker_uuid", "created_at": "2024-01-01T00:00:00Z" } }
20. 更新标签规则接口
- 说明:更新现有的标签规则
- 方法:PUT
- URL:/api/v1/workspaces/{workspaceId}/content-lockers/
- 请求示例:json
{ "name": "变量锁定器-更新", "description": "锁定代码中的变量引用,支持更多格式", "patterns": [ "\\$\\{[^}]+\\}", "\\%\\{[^}]+\\}", "\\@\\{[^}]+\\}" ] } - 响应示例:json
{ "code": 200, "message": "更新成功", "data": { "id": "locker_uuid", "updated_at": "2024-01-01T00:00:00Z" } }
21. 删除标签规则接口
- 说明:删除指定的标签规则(仅支持自定义锁定器)
- 方法:DELETE
- URL:/api/v1/workspaces/{workspaceId}/content-lockers/
- 响应示例:json
{ "code": 200, "message": "删除成功" }
22. 应用标签规则接口
- 说明:将标签规则应用到指定的Repository
- 方法:POST
- URL:/api/v1/repositories/{repositoryId}/content-lockers
- 请求示例:json
{ "locker_ids": ["locker_uuid_1", "locker_uuid_2"] } - 响应示例:json
{ "code": 200, "message": "应用成功", "data": { "applied_count": 2 } }
23. 移除标签规则接口
- 说明:从Repository中移除指定的标签规则
- 方法:DELETE
- URL:/api/v1/repositories/{repositoryId}/content-lockers/
- 响应示例:json
{ "code": 200, "message": "移除成功" }
标签规则数据库设计
1. 标签规则表 (tag_rules)
CREATE TABLE tag_rules (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(100) NOT NULL COMMENT '锁定器名称',
description TEXT COMMENT '锁定器描述',
workspace_id VARCHAR(36) NOT NULL COMMENT '所属工作空间ID',
type VARCHAR(20) NOT NULL DEFAULT 'custom' COMMENT '类型:system-系统内置, custom-自定义',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by VARCHAR(36) NOT NULL COMMENT '创建者ID',
updated_by VARCHAR(36) NOT NULL COMMENT '最后更新者ID',
INDEX idx_workspace_type (workspace_id, type),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='标签规则主表';2. 锁定器正则表达式 (tag_rule_patterns)
CREATE TABLE tag_rule_patterns (
id VARCHAR(36) PRIMARY KEY,
locker_id VARCHAR(36) NOT NULL COMMENT '所属锁定器ID',
pattern TEXT NOT NULL COMMENT '正则表达式模式',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_locker (locker_id),
FOREIGN KEY (locker_id) REFERENCES tag_rules(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='锁定器模式表';内容快照表
CREATE TABLE content_snapshots (
id VARCHAR(36) PRIMARY KEY,
repository_id VARCHAR(36) NOT NULL COMMENT '内容库ID',
content_version VARCHAR(36) NOT NULL COMMENT '内容版本ID',
filter_json JSON NOT NULL COMMENT '筛选条件JSON',
tag_rules JSON NOT NULL COMMENT '标签规则JSON,包含规则名称、描述和正则表达式模式',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
created_by VARCHAR(36) NOT NULL COMMENT '创建者ID',
INDEX idx_repository (repository_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='内容快照表';