Skip to content

内容管理

概述

内容管理专注于对单个内容库的数据管理,可以理解为类似在线表格的数据表格维护,主要涉及对于大量数据的展示、编辑、查询、过滤、排序、等操作。以及灵活的筛选构建器。

行的状态

  • 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)

sql
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)

sql
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='锁定器模式表';

内容快照表

sql
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='内容快照表';