@qingflow-tech/qingflow-cli 1.1.61-beta.4 → 1.1.61-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +3 -3
  2. package/package.json +1 -1
  3. package/pyproject.toml +1 -1
  4. package/skills/qingflow-cli/reference/builder/30-schema-fields.md +13 -0
  5. package/skills/qingflow-cli/reference/builder/70-portal.md +37 -16
  6. package/skills/qingflow-cli/reference/examples/portal/portal_apply_v1alpha1.example.json +100 -0
  7. package/skills/qingflow-cli/reference/examples/portal/portal_sections_all_types.example.json +6 -7
  8. package/src/qingflow_mcp/app_form_validator.py +20 -3
  9. package/src/qingflow_mcp/builder_facade/app_form.py +137 -17
  10. package/src/qingflow_mcp/builder_facade/models.py +164 -13
  11. package/src/qingflow_mcp/builder_facade/portals_schema.py +397 -0
  12. package/src/qingflow_mcp/builder_facade/schemas/app_form/manifest.json +14 -1
  13. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/complete.json +49 -9
  14. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/address.json +27 -0
  15. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_content_classification.json +146 -0
  16. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_content_extraction.json +146 -0
  17. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_content_generation.json +146 -0
  18. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_document_parsing.json +146 -0
  19. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_image_generation.json +146 -0
  20. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_image_recognition.json +146 -0
  21. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_machine_translation.json +146 -0
  22. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ai_text_summary.json +146 -0
  23. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/amount.json +2 -2
  24. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/attachment.json +27 -0
  25. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/date_duration.json +146 -0
  26. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/embed_field.json +146 -0
  27. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/image_select.json +146 -0
  28. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/location.json +146 -0
  29. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/number.json +2 -2
  30. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/ocr.json +146 -0
  31. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/q_linker.json +2 -2
  32. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/relation.json +27 -0
  33. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/subtable.json +29 -2
  34. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/summary.json +20 -7
  35. package/src/qingflow_mcp/builder_facade/schemas/portals/manifest.json +59 -0
  36. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/complete.json +1397 -0
  37. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/carousel.json +193 -0
  38. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/chart.json +643 -0
  39. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/favourite.json +203 -0
  40. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/filter.json +268 -0
  41. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/grid.json +265 -0
  42. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/link.json +131 -0
  43. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/task.json +199 -0
  44. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/text.json +123 -0
  45. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/components/view.json +196 -0
  46. package/src/qingflow_mcp/builder_facade/schemas/portals/v1alpha1/summary.json +800 -0
  47. package/src/qingflow_mcp/builder_facade/service.py +1104 -71
  48. package/src/qingflow_mcp/cli/commands/builder.py +114 -5
  49. package/src/qingflow_mcp/public_surface.py +2 -0
  50. package/src/qingflow_mcp/server_app_builder.py +32 -1
  51. package/src/qingflow_mcp/solution/compiler/icon_utils.py +73 -0
  52. package/src/qingflow_mcp/solution/executor.py +5 -2
  53. package/src/qingflow_mcp/tools/ai_builder_tools.py +110 -12
  54. package/src/qingflow_mcp/tools/portal_tools.py +4 -54
  55. package/src/qingflow_mcp/tools/portal_writer.py +59 -0
  56. package/src/qingflow_mcp/tools/solution_tools.py +2 -0
@@ -0,0 +1,800 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://qingflow.com/schemas/builder/portals/v1alpha1/summary.json",
4
+ "title": "Qingflow Builder Portals Declaration · summary (v1alpha1)",
5
+ "portalSummaryDescription": "门户最小声明(最简版 spec):门户名称 + 布局 + 组件清单(sections)。创建一个可用门户的最小字段集;门户全局配置/组件明细/可见性授权通过 portal_schema 传 schema_kind=complete 获取完整声明(CLI: builder portal schema --schema-kind complete)。除必填项外全部可选,缺省走后端默认。PC 为 24 列网格、mobile 为 6 列网格。组件引用使用后端唯一键(chart_id/view_key),不依赖显示名。schema 校验在别名归一之后执行,JSON Schema 只约束规范名(别名见各字段说明)。",
6
+ "$defs": {
7
+ "PortalDeclaration": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "required": [
11
+ "name",
12
+ "sections"
13
+ ],
14
+ "properties": {
15
+ "dash_key": {
16
+ "type": "string",
17
+ "dashKeyDescription": "门户唯一键;upsert 锁定已有门户(存在即更新)。缺省为创建模式,创建必须给 package_tag_id。别名 dashKey。",
18
+ "x-backend": "dash.dashKey"
19
+ },
20
+ "name": {
21
+ "type": "string",
22
+ "portalNameDescription": "门户名称。别名 dash_name/dashName。 可为空串(后端无非空校验,生产存量存在空名门户;提取产物空名透传)。",
23
+ "x-backend": "dash.dashName"
24
+ },
25
+ "package_tag_id": {
26
+ "type": "integer",
27
+ "minimum": 1,
28
+ "packageTagIdDescription": "归属应用包 tagId;创建必填(缺 dash_key 时),更新缺省沿用读面归属。别名 packageTagId/package_id/packageId。 创建(无 dash_key)时必填——由 portal_apply 实现层校验(PACKAGE_TAG_REQUIRED + 包新增权限守卫);更新(带 dash_key)缺省沿用读面归属,无所属包的门户提取产物合法缺省本字段。",
29
+ "x-backend": "dash.tags[0].tagId(POST /dash/{dashKey}/baseInfo)"
30
+ },
31
+ "sections": {
32
+ "type": "array",
33
+ "sectionsDescription": "组件清单;数组顺序即渲染顺序,提交即整体替换(replace 语义)。局部更新走 CLI 兼容参数 --patch-sections-file 或 complete 档。 空数组合法(空门户:updateDash 对空组件列表仅跳过组件重建,全局配置仍生效)。",
34
+ "items": {
35
+ "$ref": "#/$defs/Section"
36
+ },
37
+ "x-backend": "DashDetailInfo.components"
38
+ },
39
+ "layout_preset": {
40
+ "type": "string",
41
+ "enum": [
42
+ "auto",
43
+ "dashboard_2col",
44
+ "dashboard_3col"
45
+ ],
46
+ "layoutPresetDescription": "布局预设;sections 未显式给 position 时按预设自动排布(业务入口→指标卡→BI 图表→数据视图)。与显式 position 二选一,同用时 position 优先。别名 layoutPreset。",
47
+ "x-backend": "(编排层,不落库)"
48
+ },
49
+ "publish": {
50
+ "type": "boolean",
51
+ "default": true,
52
+ "publishDescription": "apply 后是否发布(true=写后发布并回读线上态;false=仅落草稿)。这是生命周期动作参数,不属于声明内容,幂等重放时用 false。",
53
+ "x-backend": "POST /dash/{dashKey}/publish"
54
+ }
55
+ }
56
+ },
57
+ "Section": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "required": [
61
+ "source_type"
62
+ ],
63
+ "sectionSummaryDescription": "门户组件(summary 档限五类稳定类型:chart/view/grid/text/link)。carousel/task/favourite/filter 见 complete 档。",
64
+ "properties": {
65
+ "title": {
66
+ "anyOf": [
67
+ {
68
+ "type": "string"
69
+ },
70
+ {
71
+ "type": "null"
72
+ }
73
+ ],
74
+ "sectionTitleDescription": "组件显示标题。空标题(null)是合法存量形态(显示标题开但标题空,读链渲染时回退图表名/视图名);创建语义缺省建议显式命名。",
75
+ "x-backend": "组件标题(DashChartInfo.title / DashChartInfo.chartComponentTitle / gridConfig.gridTitle / componentTaskTitle 等;null 落库 NULL)"
76
+ },
77
+ "source_type": {
78
+ "type": "string",
79
+ "enum": [
80
+ "chart",
81
+ "view",
82
+ "grid",
83
+ "text",
84
+ "link"
85
+ ],
86
+ "sourceTypeSummaryDescription": "组件类型。每种类型的详细配置经专项 Schema 获取(CLI: qingflow builder portal schema --schema-kind <类型>;MCP: portal_schema(schema_kind=...)),不要凭枚举名猜配置键。summary 档限五类稳定类型:chart(报表,qingflow builder portal schema --schema-kind chart)、view(数据视图,--schema-kind view)、grid(业务入口宫格,--schema-kind grid)、text(文本,--schema-kind text)、link(链接,--schema-kind link);carousel/task/favourite/filter 见 complete 档与对应专项 Schema。别名归一:大小写不敏感。后端 type 整数:chart=1/view=10/grid=2/text=5/link=4。",
87
+ "x-backend": "DashComponentInfo.type"
88
+ },
89
+ "role": {
90
+ "type": "string",
91
+ "roleDescription": "组件角色标注(编排辅助,如 metric=指标卡);影响布局预设的排布与行高约定(指标卡 rows=5/BI 图表 rows=7/数据视图 rows=11)。别名 zone/section_role。"
92
+ },
93
+ "position": {
94
+ "$ref": "#/$defs/Position",
95
+ "positionSummaryDescription": "网格位置;省略时走 layout_preset 自动排布。"
96
+ },
97
+ "chart_ref": {
98
+ "$ref": "#/$defs/ChartRef",
99
+ "chartRefSummaryDescription": "引用已存在的 QingBI 图表(chart 类型必填 chart_ref 或 chart 二选一)。"
100
+ },
101
+ "chart": {
102
+ "$ref": "#/$defs/InlineChart",
103
+ "chartInlineSummaryDescription": "内联创建 QingBI 图表(chart 类型);同一 apply 内 app_key+name+chart_type 相同且配置一致的多个区块复用同一图表,配置不同则拒绝写入。别名 inline_chart/create_chart。"
104
+ },
105
+ "view_ref": {
106
+ "$ref": "#/$defs/ViewRef",
107
+ "viewRefSummaryDescription": "引用业务视图(view 类型必填)。优先用具体业务视图,不要用「全部数据/我的数据」系统视图。"
108
+ },
109
+ "config": {
110
+ "$ref": "#/$defs/GridConfig",
111
+ "configSummaryDescription": "grid 类型的宫格配置(必填且 items 非空);其余类型 summary 档不使用 config。"
112
+ },
113
+ "text": {
114
+ "type": "string",
115
+ "textSummaryDescription": "文本内容(text 类型必填)。",
116
+ "x-backend": "ComponentTextConfig.content"
117
+ },
118
+ "url": {
119
+ "type": "string",
120
+ "maxLength": 500,
121
+ "urlSummaryDescription": "链接地址(link 类型必填),长度上限 500。",
122
+ "x-backend": "ComponentLinkConfig.linkUrl"
123
+ }
124
+ },
125
+ "allOf": [
126
+ {
127
+ "if": {
128
+ "properties": {
129
+ "source_type": {
130
+ "const": "chart"
131
+ }
132
+ },
133
+ "required": [
134
+ "source_type"
135
+ ]
136
+ },
137
+ "then": {
138
+ "anyOf": [
139
+ {
140
+ "required": [
141
+ "chart_ref"
142
+ ]
143
+ },
144
+ {
145
+ "required": [
146
+ "chart"
147
+ ]
148
+ }
149
+ ]
150
+ }
151
+ },
152
+ {
153
+ "if": {
154
+ "properties": {
155
+ "source_type": {
156
+ "const": "view"
157
+ }
158
+ },
159
+ "required": [
160
+ "source_type"
161
+ ]
162
+ },
163
+ "then": {
164
+ "required": [
165
+ "view_ref"
166
+ ]
167
+ }
168
+ },
169
+ {
170
+ "if": {
171
+ "properties": {
172
+ "source_type": {
173
+ "const": "grid"
174
+ }
175
+ },
176
+ "required": [
177
+ "source_type"
178
+ ]
179
+ },
180
+ "then": {
181
+ "required": [
182
+ "config"
183
+ ],
184
+ "properties": {
185
+ "config": {
186
+ "required": [
187
+ "items"
188
+ ],
189
+ "properties": {
190
+ "items": {}
191
+ }
192
+ }
193
+ }
194
+ }
195
+ },
196
+ {
197
+ "if": {
198
+ "properties": {
199
+ "source_type": {
200
+ "const": "text"
201
+ }
202
+ },
203
+ "required": [
204
+ "source_type"
205
+ ]
206
+ },
207
+ "then": {
208
+ "required": [
209
+ "text"
210
+ ]
211
+ }
212
+ },
213
+ {
214
+ "if": {
215
+ "properties": {
216
+ "source_type": {
217
+ "const": "link"
218
+ }
219
+ },
220
+ "required": [
221
+ "source_type"
222
+ ]
223
+ },
224
+ "then": {
225
+ "required": [
226
+ "url"
227
+ ]
228
+ }
229
+ }
230
+ ]
231
+ },
232
+ "Position": {
233
+ "type": "object",
234
+ "additionalProperties": false,
235
+ "positionDescription": "网格位置。PC 是 24 列网格(cols≤24),mobile 是 6 列网格(cols≤6);同行组件共享同一 y 与 rows,一行 cols 合计 24。mobile 可省略(缺省与 pc 同布局)。平铺别名 pc_x/pc_y/pc_w/pc_h、mobile_x/…/mobile_h 也接受,归一为本结构。标准行高:指标卡 rows=5、BI 图表 rows=7、数据视图 rows=11、业务入口 rows=4。",
236
+ "properties": {
237
+ "pc": {
238
+ "$ref": "#/$defs/PositionDetail"
239
+ },
240
+ "mobile": {
241
+ "$ref": "#/$defs/PositionDetail"
242
+ }
243
+ }
244
+ },
245
+ "PositionDetail": {
246
+ "type": "object",
247
+ "additionalProperties": false,
248
+ "positionDetailDescription": "单端位置:x=列偏移、y=行偏移、cols=占宽、rows=占高。",
249
+ "properties": {
250
+ "x": {
251
+ "type": [
252
+ "integer",
253
+ "null"
254
+ ],
255
+ "minimum": 0
256
+ },
257
+ "y": {
258
+ "type": [
259
+ "integer",
260
+ "null"
261
+ ],
262
+ "minimum": 0
263
+ },
264
+ "cols": {
265
+ "type": [
266
+ "integer",
267
+ "null"
268
+ ],
269
+ "minimum": 1
270
+ },
271
+ "rows": {
272
+ "type": [
273
+ "integer",
274
+ "null"
275
+ ],
276
+ "minimum": 1
277
+ }
278
+ },
279
+ "x-backend": "DashPosition.pc / DashPosition.mobile"
280
+ },
281
+ "ChartRef": {
282
+ "type": "object",
283
+ "additionalProperties": false,
284
+ "chartRefDescription": "已有图表引用。chart_id 或 chart_name 至少一个;按 chart_name 解析时必须给 app_key。别名 chartId/chart_key/chartKey。",
285
+ "properties": {
286
+ "app_key": {
287
+ "type": "string",
288
+ "chartRefAppKeyDescription": "图表所属应用 key。别名 appKey。",
289
+ "x-backend": "DashChartInfo(appKey 解析)"
290
+ },
291
+ "ref_kind": {
292
+ "type": "string",
293
+ "enum": [
294
+ "chart",
295
+ "bi_chart"
296
+ ],
297
+ "chartRefKindDescription": "引用面判别:chart=轻流报表(chart 表唯一键 chartKey,后端组件 type=1,写链 addChartInfos 按 chartKey 解析);bi_chart=轻析 BI 报表(bi_chart 表整型 chart_id,后端组件 type=9)。缺省 bi_chart(向后兼容)。别名 refKind/kind。",
298
+ "x-backend": "DashComponentInfo.type ∈ {1, 9}"
299
+ },
300
+ "chart_id": {
301
+ "type": "string",
302
+ "chartRefIdDescription": "图表 id(后端唯一键,回读优先携带)。别名 chartId/chart_key/chartKey。",
303
+ "x-backend": "DashComponentInfo.dashChartId"
304
+ },
305
+ "chart_name": {
306
+ "type": "string",
307
+ "chartRefNameDescription": "图表名称(按名解析时的定位键)。别名 chartName/name。"
308
+ }
309
+ }
310
+ },
311
+ "ViewRef": {
312
+ "type": "object",
313
+ "additionalProperties": false,
314
+ "required": [
315
+ "app_key"
316
+ ],
317
+ "viewRefDescription": "业务视图引用。view_key 或 view_name 至少一个;view_key 为后端唯一键,优先使用。",
318
+ "properties": {
319
+ "app_key": {
320
+ "type": "string",
321
+ "viewRefAppKeyDescription": "视图所属应用 key。别名 appKey。",
322
+ "x-backend": "ComponentViewConfig(viewgraphKey 解析)"
323
+ },
324
+ "view_key": {
325
+ "type": "string",
326
+ "viewRefKeyDescription": "视图唯一键(viewgraphKey)。别名 viewKey。"
327
+ },
328
+ "view_name": {
329
+ "type": "string",
330
+ "viewRefNameDescription": "视图名称(按名解析,重名有歧义风险)。别名 viewName。"
331
+ }
332
+ }
333
+ },
334
+ "InlineChart": {
335
+ "type": "object",
336
+ "additionalProperties": false,
337
+ "required": [
338
+ "app_key",
339
+ "name",
340
+ "chart_type"
341
+ ],
342
+ "inlineChartDescription": "内联创建的 QingBI 图表(创建后复用其 chart_id,等价于引用既有图表)。指标卡场景用 chart_type=target/indicator 且区块 rows=5。",
343
+ "properties": {
344
+ "app_key": {
345
+ "type": "string",
346
+ "inlineChartAppKeyDescription": "图表所属应用 key。"
347
+ },
348
+ "name": {
349
+ "type": "string",
350
+ "minLength": 1,
351
+ "inlineChartNameDescription": "图表名称(同 apply 内去重键之一)。"
352
+ },
353
+ "chart_type": {
354
+ "type": "string",
355
+ "enum": [
356
+ "target",
357
+ "indicator",
358
+ "summary",
359
+ "pie",
360
+ "bar",
361
+ "columnar",
362
+ "line",
363
+ "table",
364
+ "detail",
365
+ "area",
366
+ "stacked_area",
367
+ "pct_stack_area",
368
+ "funnel",
369
+ "waterfall",
370
+ "gauge",
371
+ "heatmap",
372
+ "histogram",
373
+ "treemap",
374
+ "radar",
375
+ "stacked_bar",
376
+ "pct_stack_bar",
377
+ "stacked_column",
378
+ "pct_stack_col",
379
+ "scatter",
380
+ "ring",
381
+ "rose",
382
+ "dualaxes",
383
+ "map",
384
+ "timeline"
385
+ ],
386
+ "inlineChartTypeDescription": "图表类型(与 builder chart apply 同一公开枚举)。"
387
+ },
388
+ "metric": {
389
+ "$ref": "#/$defs/ChartMetric",
390
+ "inlineChartMetricDescription": "主指标;字符串形态如 \"count(*)\"/\"sum(金额)\" 或对象形态。"
391
+ },
392
+ "metrics": {
393
+ "type": "array",
394
+ "items": {
395
+ "$ref": "#/$defs/ChartMetric"
396
+ },
397
+ "inlineChartMetricsDescription": "多指标列表(多轴/组合图)。"
398
+ },
399
+ "group_by": {
400
+ "type": "array",
401
+ "items": {
402
+ "type": "string"
403
+ },
404
+ "inlineChartGroupByDescription": "分组字段(显示名列表)。"
405
+ },
406
+ "filters": {
407
+ "type": "array",
408
+ "items": {
409
+ "$ref": "#/$defs/ChartFilterRule"
410
+ },
411
+ "inlineChartFiltersDescription": "图表数据过滤条件(单组 AND)。"
412
+ },
413
+ "dimension_field_ids": {
414
+ "type": "array",
415
+ "items": {
416
+ "type": "string"
417
+ },
418
+ "inlineChartDimensionDescription": "维度字段 id 列表(透传图表契约)。"
419
+ },
420
+ "indicator_field_ids": {
421
+ "type": "array",
422
+ "items": {
423
+ "type": "string"
424
+ },
425
+ "inlineChartIndicatorDescription": "指标字段 id 列表(透传图表契约)。"
426
+ },
427
+ "chart_id": {
428
+ "type": "string",
429
+ "inlineChartChartIdDescription": "已有图表 id(引用形态;等价 chart_ref.chart_id)。"
430
+ },
431
+ "rows": {
432
+ "type": "array",
433
+ "items": {
434
+ "type": "string"
435
+ },
436
+ "inlineChartRowsDescription": "行字段(交叉表)。",
437
+ "x-backend": "ChartUpsertPatch.rows"
438
+ },
439
+ "columns": {
440
+ "type": "array",
441
+ "items": {
442
+ "type": "string"
443
+ },
444
+ "inlineChartColumnsDescription": "列字段(交叉表)。",
445
+ "x-backend": "ChartUpsertPatch.columns"
446
+ },
447
+ "question_config": {
448
+ "type": "array",
449
+ "inlineChartQuestionConfigDescription": "图表字段配置透传(chart apply 受控面)。",
450
+ "x-backend": "ChartUpsertPatch.questionConfig"
451
+ },
452
+ "user_config": {
453
+ "type": "array",
454
+ "inlineChartUserConfigDescription": "图表用户配置透传(chart apply 受控面)。",
455
+ "x-backend": "ChartUpsertPatch.userConfig"
456
+ },
457
+ "config": {
458
+ "type": "object",
459
+ "inlineChartConfigDescription": "图表 raw 配置透传(chart apply 受控面)。",
460
+ "x-backend": "ChartUpsertPatch.config"
461
+ },
462
+ "x_metric": {
463
+ "$ref": "#/$defs/ChartMetric",
464
+ "inlineChartXMetricDescription": "X 轴指标(散点等)。"
465
+ },
466
+ "y_metric": {
467
+ "$ref": "#/$defs/ChartMetric",
468
+ "inlineChartYMetricDescription": "Y 轴指标(散点等)。"
469
+ },
470
+ "left_metric": {
471
+ "$ref": "#/$defs/ChartMetric",
472
+ "inlineChartLeftMetricDescription": "左轴指标(双轴图)。"
473
+ },
474
+ "right_metric": {
475
+ "$ref": "#/$defs/ChartMetric",
476
+ "inlineChartRightMetricDescription": "右轴指标(双轴图)。"
477
+ },
478
+ "value_metric": {
479
+ "$ref": "#/$defs/ChartMetric",
480
+ "inlineChartValueMetricDescription": "值指标。"
481
+ },
482
+ "target_metric": {
483
+ "$ref": "#/$defs/ChartMetric",
484
+ "inlineChartTargetMetricDescription": "目标值指标。"
485
+ }
486
+ }
487
+ },
488
+ "ChartMetric": {
489
+ "inlineChartMetricShapeDescription": "聚合指标:字符串形态(如 \"count(*)\"、\"sum(金额)\",裸字段名默认 sum)或对象 {op, field_name, alias}。op 常用 count/sum/avg/max/min。",
490
+ "oneOf": [
491
+ {
492
+ "type": "string",
493
+ "minLength": 1
494
+ },
495
+ {
496
+ "type": "object",
497
+ "additionalProperties": false,
498
+ "required": [
499
+ "op"
500
+ ],
501
+ "properties": {
502
+ "op": {
503
+ "type": "string",
504
+ "inlineChartMetricOpDescription": "聚合方式(count/sum/avg/max/min…)。别名 operation/agg/aggregate/aggregation。"
505
+ },
506
+ "field_name": {
507
+ "type": "string",
508
+ "inlineChartMetricFieldDescription": "聚合字段显示名;count(*) 时省略。别名 field/fieldName/name。"
509
+ },
510
+ "alias": {
511
+ "type": "string",
512
+ "inlineChartMetricAliasDescription": "指标别名(图例显示)。"
513
+ }
514
+ }
515
+ }
516
+ ]
517
+ },
518
+ "ChartFilterRule": {
519
+ "type": "object",
520
+ "additionalProperties": false,
521
+ "required": [
522
+ "field_name"
523
+ ],
524
+ "chartFilterRuleDescription": "图表过滤规则。is_empty/not_empty 不带 values,其余 operator 必须带非空 values。别名 field/fieldName/name。",
525
+ "properties": {
526
+ "field_name": {
527
+ "type": "string"
528
+ },
529
+ "operator": {
530
+ "type": "string",
531
+ "enum": [
532
+ "eq",
533
+ "neq",
534
+ "in",
535
+ "contains",
536
+ "gte",
537
+ "lte",
538
+ "is_empty",
539
+ "not_empty",
540
+ "belongs_to"
541
+ ],
542
+ "default": "eq",
543
+ "chartFilterOperatorDescription": "比较符。别名 op。 belongs_to=成员/部门归属(后端 JUDGE_BELONG_TO=13,公式引擎全支持)。"
544
+ },
545
+ "values": {
546
+ "type": "array",
547
+ "chartFilterValuesDescription": "比较值列表;单值也可写作 value(归一为单元素 values)。"
548
+ }
549
+ }
550
+ },
551
+ "GridConfig": {
552
+ "type": "object",
553
+ "additionalProperties": false,
554
+ "required": [
555
+ "items"
556
+ ],
557
+ "gridConfigShapeDescription": "业务入口宫格配置;items 必须含真实条目,不接受空宫格。声明键与后端 ComponentGridInfo 键一致(camelCase):gridTitle/beingShowTitle/items。",
558
+ "properties": {
559
+ "gridTitle": {
560
+ "type": "string",
561
+ "gridTitleShapeDescription": "宫格标题(缺省用 section.title)。",
562
+ "x-backend": "ComponentGridInfo.gridTitle"
563
+ },
564
+ "beingShowTitle": {
565
+ "type": "boolean",
566
+ "default": true,
567
+ "gridShowTitleShapeDescription": "是否显示宫格标题。",
568
+ "x-backend": "ComponentGridInfo.beingShowTitle"
569
+ },
570
+ "items": {
571
+ "type": "array",
572
+ "gridItemsShapeDescription": "入口条目列表(ordinal 缺省按数组顺序)。 空数组合法(空入口宫格:后端建 grid 行、0 item 行,round-trip 保真)。",
573
+ "items": {
574
+ "$ref": "#/$defs/GridItem"
575
+ }
576
+ }
577
+ },
578
+ "x-backend": "ComponentGridInfo"
579
+ },
580
+ "GridItem": {
581
+ "type": "object",
582
+ "additionalProperties": false,
583
+ "required": [
584
+ "type",
585
+ "jumpMode",
586
+ "title"
587
+ ],
588
+ "gridItemShapeDescription": "单个入口条目。grid 的 config 声明键与后端 ComponentGridItemInfo 键一致(camelCase);Python 端 section.config 直接透传。",
589
+ "properties": {
590
+ "type": {
591
+ "type": "integer",
592
+ "gridItemTypeDescription": "入口类型:1=应用,2=门户,3=应用包,4=外链。",
593
+ "x-backend": "ComponentGridItemInfo.type"
594
+ },
595
+ "jumpMode": {
596
+ "type": "integer",
597
+ "gridJumpModeDescription": "跳转方式:1=应用内页,2=新页面。",
598
+ "x-backend": "ComponentGridItemInfo.jumpMode"
599
+ },
600
+ "linkAppKey": {
601
+ "type": "string",
602
+ "gridItemAppKeyDescription": "目标应用 key(type=1 时使用)。",
603
+ "x-backend": "ComponentGridItemInfo.linkAppKey"
604
+ },
605
+ "linkFormType": {
606
+ "type": [
607
+ "integer",
608
+ "null"
609
+ ],
610
+ "gridItemFormTypeDescription": "目标应用页面形态(type=1 时使用)。",
611
+ "x-backend": "ComponentGridItemInfo.linkFormType"
612
+ },
613
+ "linkDashKey": {
614
+ "type": [
615
+ "string",
616
+ "null"
617
+ ],
618
+ "gridItemDashKeyDescription": "目标门户 key(type=2 时使用)。",
619
+ "x-backend": "ComponentGridItemInfo.linkDashKey"
620
+ },
621
+ "linkTagId": {
622
+ "type": [
623
+ "integer",
624
+ "null"
625
+ ],
626
+ "gridItemTagIdDescription": "目标应用包 tagId(type=3 时使用)。",
627
+ "x-backend": "ComponentGridItemInfo.linkTagId"
628
+ },
629
+ "linkUrl": {
630
+ "type": [
631
+ "string",
632
+ "null"
633
+ ],
634
+ "maxLength": 500,
635
+ "gridItemUrlDescription": "外链地址(type=4 时使用)。",
636
+ "x-backend": "ComponentGridItemInfo.linkUrl"
637
+ },
638
+ "title": {
639
+ "type": "string",
640
+ "gridItemTitleDescription": "入口标题。",
641
+ "x-backend": "ComponentGridItemInfo.title"
642
+ },
643
+ "customTitle": {
644
+ "type": "string",
645
+ "gridItemCustomTitleDescription": "自定义标题(beingCustomTitle=true 时生效)。",
646
+ "x-backend": "ComponentGridItemInfo.customTitle"
647
+ },
648
+ "beingCustomTitle": {
649
+ "type": "boolean",
650
+ "default": false,
651
+ "gridItemCustomTitleSwitchDescription": "是否启用自定义标题。",
652
+ "x-backend": "ComponentGridItemInfo.beingCustomTitle"
653
+ },
654
+ "iconUrl": {
655
+ "type": "string",
656
+ "gridItemIconDescription": "入口图标 URL(可选,缺省按目标解析)。",
657
+ "x-backend": "ComponentGridItemInfo.iconUrl"
658
+ },
659
+ "ordinal": {
660
+ "type": [
661
+ "integer",
662
+ "null"
663
+ ],
664
+ "gridItemOrdinalDescription": "排序(缺省按数组顺序)。",
665
+ "x-backend": "ComponentGridItemInfo.ordinal"
666
+ }
667
+ }
668
+ }
669
+ },
670
+ "$ref": "#/$defs/PortalDeclaration",
671
+ "x-qingflow-detail-query": {
672
+ "currentKind": "summary",
673
+ "tool": "portal_schema",
674
+ "cli": "qingflow builder portal schema --schema-kind KIND",
675
+ "argument": "schema_kind",
676
+ "kinds": [
677
+ "summary",
678
+ "complete",
679
+ "chart",
680
+ "view",
681
+ "grid",
682
+ "filter",
683
+ "text",
684
+ "link",
685
+ "carousel",
686
+ "task",
687
+ "favourite"
688
+ ],
689
+ "kindDescriptions": {
690
+ "summary": "门户名称 + 布局 + 组件清单(五类稳定组件类型)。",
691
+ "complete": "完整门户声明:全局配置 + 九类组件明细 + 可见性授权;summary 是它的最小子集。",
692
+ "chart": "报表组件:chart_ref 已有图表引用 / chart 内联创建(QingBI 全类型、指标、过滤、双轴)。",
693
+ "view": "数据视图组件:视图引用(view_key 优先)与组件展示配置。",
694
+ "grid": "业务入口宫格:入口条目(应用/门户/外链)、图标、自定义标题、排序。",
695
+ "filter": "筛选组件:作用图表与筛选规则组(语义 raw/unstable,不建议主自动化路径)。",
696
+ "text": "文本组件:富文本内容。",
697
+ "link": "链接组件:地址(≤500)与登录鉴权。",
698
+ "carousel": "轮播组件:数据源应用 + 标题/图片/链接字段绑定 + 滚动配置。",
699
+ "task": "待办组件:提示文案与任务条目。",
700
+ "favourite": "收藏组件:预置收藏条目。"
701
+ },
702
+ "detailQueryDescription": "每种组件类型的详细配置都有自包含专项 Schema:按需调用 portal_schema 传对应 schema_kind(CLI: qingflow builder portal schema --schema-kind chart|view|grid|filter|text|link|carousel|task|favourite);专项已内联其引用的定义,可独立交给 JSON Schema 校验器。",
703
+ "readSources": {
704
+ "chartIds": "已有图表用 chart 面读取 chart_id;内联创建则直接在 section.chart 声明。",
705
+ "viewKeys": "视图唯一键用 qingflow builder views get --app-key APP 回读。",
706
+ "existingPortal": "既有门户声明用 qingflow builder portal get --dash-key K --schema-kind summary|complete 回读。"
707
+ }
708
+ },
709
+ "x-qingflow-create-defaults": {
710
+ "createDefaultsDescription": "以下是 portal_apply 当前创建路径在相应片段完全省略时组装的后端值。default 和 x-qingflow-* 是契约注解,通用 JSON Schema 校验器不会自动填值。更新已有门户时 sections 是 replace 语义,不要把创建默认值当作现有值。",
711
+ "name": "未命名门户(仅当创建且未给 name 时)",
712
+ "visibility": {
713
+ "mode": "workspace",
714
+ "external_mode": "not"
715
+ },
716
+ "hide_copyright": false,
717
+ "global_config": {
718
+ "auto_refresh": false,
719
+ "interval": 60
720
+ },
721
+ "publish": true
722
+ },
723
+ "x-qingflow-capability-boundary": {
724
+ "contract": "仅列出 portal_apply 当前可写字段。",
725
+ "backendKnownUnsupported": {
726
+ "carousel_task_favourite": "后端 DashComponentInfo 支持 carousel(3)/task(8)/favourite(7) 组件,summary 档不开放;详细配置经 qingflow builder portal schema --schema-kind carousel|task|favourite 获取(complete 档承载)。",
727
+ "filter_component": "filter(6) 组件后端语义 raw/unstable,不进 summary;详细配置经 qingflow builder portal schema --schema-kind filter 获取(complete 档受控承载)。",
728
+ "watermark": "工作区水印(beingWatermark/watermarkConfig)是工作区级配置,不属于门户声明。",
729
+ "overall_style": "overallConfigBO/styleTemplateId 全局样式,见 complete 档(键集以 dataset 实测形态校准)。"
730
+ }
731
+ },
732
+ "examples": [
733
+ {
734
+ "name": "业务工作台",
735
+ "package_tag_id": 2030703,
736
+ "sections": [
737
+ {
738
+ "title": "业务入口",
739
+ "source_type": "grid",
740
+ "position": {
741
+ "pc": {
742
+ "x": 0,
743
+ "y": 0,
744
+ "cols": 24,
745
+ "rows": 4
746
+ }
747
+ },
748
+ "config": {
749
+ "gridTitle": "业务入口",
750
+ "beingShowTitle": true,
751
+ "items": [
752
+ {
753
+ "type": 1,
754
+ "jumpMode": 1,
755
+ "linkAppKey": "APP_KEY_DEVICE",
756
+ "linkFormType": 1,
757
+ "title": "设备台账"
758
+ }
759
+ ]
760
+ }
761
+ },
762
+ {
763
+ "title": "设备总数",
764
+ "source_type": "chart",
765
+ "role": "metric",
766
+ "position": {
767
+ "pc": {
768
+ "x": 0,
769
+ "y": 4,
770
+ "cols": 6,
771
+ "rows": 5
772
+ }
773
+ },
774
+ "chart": {
775
+ "app_key": "APP_KEY_DEVICE",
776
+ "name": "设备总数",
777
+ "chart_type": "target",
778
+ "metric": "count(*)"
779
+ }
780
+ },
781
+ {
782
+ "title": "异常设备",
783
+ "source_type": "view",
784
+ "position": {
785
+ "pc": {
786
+ "x": 0,
787
+ "y": 9,
788
+ "cols": 24,
789
+ "rows": 11
790
+ }
791
+ },
792
+ "view_ref": {
793
+ "app_key": "APP_KEY_DEVICE",
794
+ "view_key": "VIEW_KEY_ABNORMAL_DEVICES"
795
+ }
796
+ }
797
+ ]
798
+ }
799
+ ]
800
+ }