在线演示

真实 schema

上面那个演示是为了展示控件而编的 schema。这一个不是:字段、kind、diff_hint 与上限全部照抄编辑引擎注册的 catalog.work,config 一行没写,来自 catalogConfig()。

catalog.work

十八个字段,含四个只有对象行才能表达的列表、两个图片列表,以及一个被抑制的标题行。打开上面的开关可以看服务端拒绝时错误落到哪个字段上。

接线
import { mergeSchemaFaces } from '@nextmoe/edit-ui-core'
import { catalogConfig } from '@nextmoe/edit-ui-catalog'

// 编辑 API 有两张脸:actor-caps 面知道你能不能改,
// GET /v2/catalog/schemas/{object} 面知道值长什么样。合并后交给表单。
const fields = mergeSchemaFaces(capsFields, valueFields)

// config 不用手写:五十个字段的控件、词表、列类型与身份键都已经在预设里。
const config = catalogConfig('catalog.work', {
  searchEntities: { character, credit_name, label, role, engine, series, tag },
  uploadImage,
  resolveImage
})

// vocabularies 传 GET /v2/vocabularies 的结果:预设没覆盖的字段
// (比如引擎新增的)会用词表推导出选项,而不是降级为只读。
显示名

不能为空,最多 500 字。

标题

至少一条官方标题,最多 100 条。标题最多 500 字。只有别名可以不填语言。

已隐藏
4 / 100

update:patch —— 只包含真正改动过的字段,且已经是服务端要求的 JSON 类型:整数列发整数,抑制集合按码位升序去重。

{}

为什么需要预设

schema 接口只回答 key / kind / diff_hint / 上限,从不回答元素形状、枚举词表和可空性。

list + items 同时覆盖两种完全不同的东西

catalog.work.links 的元素是纯 URL 字符串,catalog.work.titles 的元素是 {lang, title, latin, kind} 对象,两者的 schema 一模一样。没有预设时,标题字段会被当成纯文本列表渲染成 [object Object],用户一动就把整个字段写坏——所以组件现在会按运行时的值降级为只读,而预设直接给出正确的行编辑器。

读接口给字符串,写接口要整数

公开 API 的 content_rating 是 all_ages / sensitive / r18,编辑引擎要的是 0 / 1 / 2;gender 是 1 / 2 / 3,没有 0。照着公开词表拼出来的选项,每一次提交都是 422。预设里的值全部取自引擎自己的字段规格。