bugfix
This commit is contained in:
parent
c02441e26e
commit
29e00b4697
5
doc.sh
Normal file
5
doc.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
sources=$(find bricks -name "*.js" -exec grep -l '.register(' {} \; -print|sort -u)
|
||||||
|
for s in $sources
|
||||||
|
do
|
||||||
|
t2t -p prompt.md -o docs/ai $s
|
||||||
|
done
|
||||||
68
docs/ai/accordion.md
Normal file
68
docs/ai/accordion.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# Accordion
|
||||||
|
用于实现手风琴式折叠面板效果,允许用户通过点击选项卡切换显示对应的内容区域;类型为容器控件,继承自bricks.VBox。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
| 方法名 | 功能说明 | 参数/选项 |
|
||||||
|
|--------|----------|-----------|
|
||||||
|
| `constructor(opts)` | 初始化手风琴控件,创建选项卡按钮并默认展开第一个选项卡内容 | - `item_size`:选项卡高度,默认值为`25px` <br> - `items`:选项卡配置数组,每个项需包含`name`(唯一标识)、`icon`(图标类名)、`label`(选项卡文本)、`content`(选项卡对应的内容控件JSON)、`refresh`(是否每次切换都重新构建内容,默认`false`) <br> - `item_css`:选项卡按钮的CSS类,默认`accordion-button` <br> - `content_css`:内容区域的CSS类,默认`accordion-content` |
|
||||||
|
| `async change_content(event)` | 点击选项卡按钮时触发,切换显示对应的内容区域。若`refresh`为`true`或内容未构建过,则重新构建内容控件 | - `event`:事件对象,`target.bricks_widget`指向被点击的选项卡按钮 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
| 事件名 | 触发时机 |
|
||||||
|
|--------|----------|
|
||||||
|
| `click`(选项卡按钮) | 用户点击手风琴的任意选项卡按钮时触发,进而执行内容切换逻辑 |
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "demo_accordion", // 手风琴控件唯一ID
|
||||||
|
"widgettype": "Accordion", // 控件类型为Accordion
|
||||||
|
"options": {
|
||||||
|
"item_size": "30px", // 自定义选项卡高度为30px
|
||||||
|
"items": [ // 选项卡配置数组
|
||||||
|
{
|
||||||
|
"name": "tab_home", // 选项卡唯一标识
|
||||||
|
"icon": "icon-home", // 选项卡图标类名
|
||||||
|
"label": "首页", // 选项卡文本
|
||||||
|
"content": { // 首页对应的内容控件(Label)
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "欢迎使用手风琴控件演示",
|
||||||
|
"align": "center"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tab_info",
|
||||||
|
"icon": "icon-info",
|
||||||
|
"label": "信息",
|
||||||
|
"content": { // 信息页对应的内容控件(VBox容器,包含Label和Button)
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"align": "left"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {"text": "手风琴支持动态加载内容"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {"label": "查看详情"},
|
||||||
|
"binds": [ // 按钮事件绑定
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "infoBtn", // 按钮ID
|
||||||
|
"event": "click",
|
||||||
|
"target": "demo_accordion",
|
||||||
|
"script": "console.log('点击了查看详情按钮');" // 执行自定义脚本
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
116
docs/ai/asr.md
Normal file
116
docs/ai/asr.md
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# ASRClient
|
||||||
|
|
||||||
|
用于实现语音识别(ASR,Automatic Speech Recognition)功能的前端控件。用户点击按钮开始录音,控件通过浏览器的 `MediaRecorder API` 获取麦克风音频流,并将音频数据编码为 Base64 后通过 WebSocket 实时发送至后端服务器进行语音识别。识别结果由服务器返回,控件触发 `transtext` 事件将文本内容传递给上层逻辑处理。
|
||||||
|
|
||||||
|
**类型**:普通控件(继承自 `bricks.VBox`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`toggle_button()`**
|
||||||
|
切换录音状态(开始/停止),并更新按钮图标。
|
||||||
|
|
||||||
|
- **`start_recording()`**
|
||||||
|
异步方法,请求用户授权麦克风权限,启动 `MediaRecorder` 每秒采集音频片段并通过 WebSocket 发送。
|
||||||
|
|
||||||
|
- **`stop_recording()`**
|
||||||
|
停止 `MediaRecorder` 录音,关闭媒体流。
|
||||||
|
|
||||||
|
- **`response_data(event)`**
|
||||||
|
WebSocket 接收到服务器消息时调用,解析 JSON 数据并派发 `transtext` 事件。
|
||||||
|
|
||||||
|
- **`response_log(event)`**
|
||||||
|
默认的日志处理函数,在控制台输出识别结果,可通过重写来自定义日志行为。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`start`**
|
||||||
|
当用户点击按钮开始录音时触发,无参数。
|
||||||
|
|
||||||
|
- **`stop`**
|
||||||
|
当用户停止录音时触发,无参数。
|
||||||
|
|
||||||
|
- **`transtext`**
|
||||||
|
服务器返回识别文本时触发,参数结构如下:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content": "识别出的文本",
|
||||||
|
"speaker": "说话人标识(可选)",
|
||||||
|
"start": "起始时间戳",
|
||||||
|
"end": "结束时间戳"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "asr_widget",
|
||||||
|
"widgettype": "ASRClient",
|
||||||
|
"options": {
|
||||||
|
// 开始录音时显示的图标(可选)
|
||||||
|
"start_icon": "imgs/start_recording.svg",
|
||||||
|
// 停止录音时显示的图标(可选)
|
||||||
|
"stop_icon": "imgs/stop_recording.png",
|
||||||
|
// WebSocket 连接地址(必须)
|
||||||
|
"ws_url": "wss://example.com/api/asr/stream",
|
||||||
|
// 图标控件的额外配置(如大小、样式等,可选)
|
||||||
|
"icon_options": {
|
||||||
|
"width": "50px",
|
||||||
|
"height": "50px"
|
||||||
|
},
|
||||||
|
// 发送给 WebSocket 的附加参数(例如模型类型、语言等)
|
||||||
|
"ws_params": {
|
||||||
|
"lang": "zh-CN",
|
||||||
|
"model": "asr-general"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "asr_widget",
|
||||||
|
"event": "transtext",
|
||||||
|
"target": "text_display",
|
||||||
|
"dispatch_event": "update_text",
|
||||||
|
"params": {
|
||||||
|
"from": "ASR"
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"msg": "{content}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "asr_widget",
|
||||||
|
"event": "start",
|
||||||
|
"target": "logger",
|
||||||
|
"script": "console.log('ASR recording started...');"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "asr_widget",
|
||||||
|
"event": "stop",
|
||||||
|
"target": "logger",
|
||||||
|
"script": "console.log('ASR recording stopped.');"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **说明与注释**:
|
||||||
|
>
|
||||||
|
> - `widgettype: "ASRClient"` 表示使用已注册的语音识别控件。
|
||||||
|
> - `options.ws_url` 必须是一个有效的 WebSocket 地址(`ws://` 或 `wss://`)。
|
||||||
|
> - `binds` 中监听了 `transtext` 事件,将识别结果动态更新到 ID 为 `text_display` 的控件中。
|
||||||
|
> - 使用 `{content}` 占位符可在运行时自动替换为实际识别内容(基于 bricks 数据绑定机制)。
|
||||||
|
> - 可结合 `registerfunction` 调用全局函数进一步处理识别结果,如语义理解、TTS 回复等。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
📌 **应用场景建议**:
|
||||||
|
适用于语音输入、实时字幕、语音助手交互等需要前端采集语音并实时获取识别结果的场景。需确保后端支持 WebSocket 流式 ASR 解码。
|
||||||
282
docs/ai/audio.md
Normal file
282
docs/ai/audio.md
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
# AudioPlayer
|
||||||
|
|
||||||
|
用于播放音频文件的普通控件,继承自 `JsWidget`。支持本地或远程音频资源播放、自动播放、播放控制(暂停/继续)、播放队列管理以及通过流式响应动态加载多个音频片段。
|
||||||
|
|
||||||
|
**类型:** 普通控件(非容器控件)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `play()`
|
||||||
|
异步方法,开始播放当前音频。如果音频已暂停,则恢复播放。
|
||||||
|
|
||||||
|
- `toggle_play()`
|
||||||
|
异步方法,切换播放/暂停状态。若当前为暂停状态则播放,否则暂停。
|
||||||
|
|
||||||
|
- `set_url(url)`
|
||||||
|
设置音频源并立即开始播放。参数 `url` 为音频文件的 URL 地址。
|
||||||
|
|
||||||
|
- `set_source(url)`
|
||||||
|
设置音频源(仅更新 `<source>` 标签和 `audio.src`),不自动播放。
|
||||||
|
|
||||||
|
- `add_url(url)`
|
||||||
|
将指定 URL 添加到播放列表末尾。如果当前音频处于“错误”或“结束”状态,则立即切换播放该音频;否则加入队列等待自动播放下一首。
|
||||||
|
|
||||||
|
- `get_status()`
|
||||||
|
获取当前播放器的状态,返回值为以下之一:
|
||||||
|
- `"playing"`:正在播放
|
||||||
|
- `"paused"`:已暂停
|
||||||
|
- `"loading"`:加载中(数据不足)
|
||||||
|
- `"ended"`:播放结束
|
||||||
|
- `"error"`:发生错误
|
||||||
|
|
||||||
|
- `set_stream_urls(response)`
|
||||||
|
接收一个 `Response` 对象(如从 `fetch` 流式接口获取),解析其流中的每一段音频 URL,并逐个播放。适用于服务器推送多个音频片段的场景。
|
||||||
|
|
||||||
|
- `play_srclist(event)`
|
||||||
|
内部异步方法,用于从 `srcList` 中按顺序播放未播放过的音频片段。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `ended`
|
||||||
|
当所有音频播放完毕(包括播放列表中的最后一个)时触发。可用于通知上层组件播放完成。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "player1",
|
||||||
|
"widgettype": "AudioPlayer",
|
||||||
|
"options": {
|
||||||
|
"url": "/audio/intro.mp3", // 初始音频URL
|
||||||
|
"autoplay": true // 是否自动播放
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_toggle",
|
||||||
|
"event": "click",
|
||||||
|
"target": "player1",
|
||||||
|
"method": "toggle_play",
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_next",
|
||||||
|
"event": "click",
|
||||||
|
"target": "player1",
|
||||||
|
"method": "add_url",
|
||||||
|
"params": {
|
||||||
|
"url": "/audio/chapter2.mp3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "player1",
|
||||||
|
"event": "ended",
|
||||||
|
"target": "Popup",
|
||||||
|
"script": "bricks.alert('播放完成!');"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 此控件 ID 为 `player1`,初始加载并自动播放 `/audio/intro.mp3`。
|
||||||
|
> - 点击 ID 为 `btn_toggle` 的按钮会调用 `toggle_play()` 方法实现播放/暂停切换。
|
||||||
|
> - 点击 `btn_next` 按钮将添加新的音频到播放队列。
|
||||||
|
> - 当音频播放结束后,弹出提示框告知用户“播放完成”。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# AudioRecorder
|
||||||
|
|
||||||
|
音频录制控件,继承自 `HBox`(水平布局容器控件)。提供麦克风录音功能,支持 WAV 格式录音、实时录音时长显示、录音开始/结束事件派发,并可配置上传 URL 实现录音文件自动上传。
|
||||||
|
|
||||||
|
**类型:** 容器控件(继承自 HBox,包含子控件)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `start_recording()`
|
||||||
|
开始录音。若尚未打开麦克风权限,则先请求授权并初始化录音器。
|
||||||
|
|
||||||
|
- `stop_recording()`
|
||||||
|
停止录音,生成 Blob 对象并派发 `record_ended` 事件,携带录音数据与播放 URL。
|
||||||
|
|
||||||
|
- `pause_recording()`
|
||||||
|
暂停录音(如有支持)。
|
||||||
|
|
||||||
|
- `resume_recording()`
|
||||||
|
恢复暂停的录音。
|
||||||
|
|
||||||
|
- `upload()`
|
||||||
|
异步方法,将最近一次录音的数据通过 FormData 上传至 `upload_url` 配置的地址,使用 POST 请求发送文件 `recorder.wav`。
|
||||||
|
|
||||||
|
- `download()`
|
||||||
|
下载当前录音文件,生成临时链接并触发浏览器下载行为。
|
||||||
|
|
||||||
|
- `recOpen()` / `recClose()`
|
||||||
|
内部方法,用于打开/关闭麦克风访问权限及初始化 Recorder 实例。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `record_started`
|
||||||
|
当录音开始前触发,可用于 UI 更新(如切换图标、启用播放预览等)。
|
||||||
|
|
||||||
|
- `record_ended`
|
||||||
|
录音停止后触发,携带数据对象 `{ data: Blob, url: string, duration: number }`,可用于预览或上传。
|
||||||
|
|
||||||
|
- `uploaded`
|
||||||
|
成功上传录音后触发,携带服务器返回结果 `ret`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "recorder1",
|
||||||
|
"widgettype": "AudioRecorder",
|
||||||
|
"options": {
|
||||||
|
"upload_url": "/api/upload_audio", // 录音上传地址
|
||||||
|
"start_icon": "imgs/start_recording.svg", // 开始录音图标
|
||||||
|
"stop_icon": "imgs/stop_recording.svg", // 停止录音图标
|
||||||
|
"icon_rate": 2 // SVG 图标缩放比例
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "recorder1",
|
||||||
|
"event": "record_started",
|
||||||
|
"target": "status_text",
|
||||||
|
"dispatch_event": "set_text",
|
||||||
|
"params": {
|
||||||
|
"text": "正在录音..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "recorder1",
|
||||||
|
"event": "record_ended",
|
||||||
|
"target": "status_text",
|
||||||
|
"dispatch_event": "set_text",
|
||||||
|
"params": {
|
||||||
|
"text": "录音结束,正在上传..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "registerfunction",
|
||||||
|
"wid": "recorder1",
|
||||||
|
"event": "uploaded",
|
||||||
|
"rfname": "onAudioUploaded",
|
||||||
|
"params": {
|
||||||
|
"recorderId": "recorder1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_download",
|
||||||
|
"event": "click",
|
||||||
|
"target": "recorder1",
|
||||||
|
"method": "download",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 控件 ID 为 `recorder1`,使用自定义图标进行视觉反馈。
|
||||||
|
> - 录音开始时,向 `status_text` 文本控件派发 `set_text` 事件更新状态。
|
||||||
|
> - 录音结束后提示“正在上传”,并在上传成功后调用全局注册函数 `onAudioUploaded` 处理后续逻辑。
|
||||||
|
> - 提供一个下载按钮 `btn_download`,允许用户手动下载录音文件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# TextedAudioPlayer
|
||||||
|
|
||||||
|
带文本同步显示的音频播放器,继承自 `VBox`(垂直容器控件)。常用于语音朗读+字幕同步场景。能够接收流式 JSON 数据,其中包含音频 Base64 编码片段和对应文本内容,实现边接收边播放边展示文本的效果。
|
||||||
|
|
||||||
|
**类型:** 容器控件(可包含子控件)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `set_stream_urls(response)`
|
||||||
|
接收一个 `Response` 流对象,从中读取 JSON 数据流(每个 JSON 包含 `audio` 和 `text` 字段),解码后缓存至内部队列。
|
||||||
|
|
||||||
|
- `load_stream_data(json)`
|
||||||
|
内部异步方法,处理每一个流式到达的 JSON 数据块,将其推入播放缓冲区,并尝试触发播放。
|
||||||
|
|
||||||
|
- `playnext()`
|
||||||
|
从缓冲区取出下一条音频+文本数据,设置音频播放,并更新文本区域内容。当播放完当前音频后自动触发下一首。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件对外暴露,但内部监听 `AudioPlayer` 的 `ended` 事件以驱动连续播放。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "texted_player",
|
||||||
|
"widgettype": "TextedAudioPlayer",
|
||||||
|
"options": {
|
||||||
|
"height": "300px",
|
||||||
|
"width": "100%"
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "btn_start_read",
|
||||||
|
"event": "click",
|
||||||
|
"target": "texted_player",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/stream-audio-text",
|
||||||
|
"method": "POST",
|
||||||
|
"params": {
|
||||||
|
"text": "{{input_text}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mode": "replace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "texted_player",
|
||||||
|
"event": "ended",
|
||||||
|
"target": "bricks",
|
||||||
|
"method": "notify",
|
||||||
|
"params": {
|
||||||
|
"message": "全部朗读完成"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 控件 ID 为 `texted_player`,是一个垂直布局容器,内部包含一个 `AudioPlayer` 和一个带滚动的文本区域。
|
||||||
|
> - 点击 `btn_start_read` 按钮时,向 `/api/stream-audio-text` 发起 POST 请求,传入动态文本内容(例如来自输入框的 `input_text`)。
|
||||||
|
> - 服务器以流式 JSON 响应返回多个 `{ audio: base64str, text: '...' }` 数据块,客户端逐步播放音频并同步显示文本。
|
||||||
|
> - 所有内容播放完成后,调用 `bricks.notify` 显示完成通知。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> ✅ **备注:**
|
||||||
|
> 上述三个控件均已通过 `bricks.Factory.register` 注册,可在 `.ui` 文件中直接使用 `widgettype` 调用。
|
||||||
|
> 使用时需确保引入依赖库:[Recorder.js](https://gitee.com/xiangyuecn/Recorder) 用于录音功能。
|
||||||
88
docs/ai/bar.md
Normal file
88
docs/ai/bar.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# ChartBar
|
||||||
|
|
||||||
|
ChartBar 是一个基于 ECharts 的柱状图控件,用于可视化展示分类数据的数值对比。该控件继承自 `bricks.EchartsExt`,属于**普通控件**(非容器控件),不支持包含子控件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`values_from_data(data, name)`**
|
||||||
|
从传入的数据数组中提取指定字段的值,返回值数组。常用于构建 ECharts 的 series 数据。
|
||||||
|
|
||||||
|
- **`lineinfo_from_data(data, name)`**
|
||||||
|
根据字段名生成单个柱状序列(series)的配置对象,类型为 `'bar'`。
|
||||||
|
|
||||||
|
- **`setup_options(data)`**
|
||||||
|
核心方法,接收原始数据并生成完整的 ECharts 配置项(options),包括:
|
||||||
|
- tooltip:轴触发提示
|
||||||
|
- legend:图例(基于 nameField 字段)
|
||||||
|
- xAxis:类别轴(横轴)
|
||||||
|
- yAxis:数值轴(纵轴)
|
||||||
|
- series:多个柱状图序列
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
该控件未定义自定义事件,但继承了 `EchartsExt` 基类所支持的标准事件,例如:
|
||||||
|
|
||||||
|
- `'click'`:用户点击图表时触发,可通过 binds 监听。
|
||||||
|
- `'legendselectchanged'`:图例选择变化时触发。
|
||||||
|
|
||||||
|
这些事件可用于与其他控件联动或执行脚本逻辑。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "chart_sales_bar",
|
||||||
|
"widgettype": "ChartBar",
|
||||||
|
"options": {
|
||||||
|
"data_url": "/api/sales/data", // 从后端接口获取数据
|
||||||
|
"method": "GET", // 请求方式,默认可省略
|
||||||
|
"params": { // 请求参数
|
||||||
|
"year": 2024,
|
||||||
|
"region": "north"
|
||||||
|
},
|
||||||
|
"nameField": "month", // 用作 X 轴显示的字段(如月份)
|
||||||
|
"valueFields": ["sales", "target"] // 多个指标字段,分别绘制为不同柱子
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "btn_refresh_chart",
|
||||||
|
"event": "click",
|
||||||
|
"target": "chart_sales_bar",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "ChartBar",
|
||||||
|
"options": {
|
||||||
|
"data_url": "/api/sales/data",
|
||||||
|
"params": {
|
||||||
|
"year": "{{widget('input_year').getValue()}}", // 动态取输入框年份
|
||||||
|
"region": "north"
|
||||||
|
},
|
||||||
|
"nameField": "month",
|
||||||
|
"valueFields": ["sales", "target"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mode": "replace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "chart_sales_bar",
|
||||||
|
"event": "click",
|
||||||
|
"script": "async function({ params }) { console.log('柱状图点击:', params); }",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - 此控件通过 `data_url` 和 `params` 自动加载远程数据并渲染柱状图。
|
||||||
|
> - `nameField` 定义 X 轴标签(如 “1月”, “2月”)。
|
||||||
|
> - `valueFields` 支持多个字段,每个字段对应一个柱状系列(如销售额、目标额)。
|
||||||
|
> - 使用 `binds` 实现按钮刷新图表和点击日志输出。
|
||||||
|
> - `{{widget(...)}}` 表达式可在运行时动态获取其他控件的值,实现交互过滤。
|
||||||
106
docs/ai/brief.md
Normal file
106
docs/ai/brief.md
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# bricks框架简介
|
||||||
|
## 目录
|
||||||
|
* bricks目标
|
||||||
|
* bricks概念
|
||||||
|
* bricks开发方法
|
||||||
|
* bricks运行
|
||||||
|
|
||||||
|
## bricks目标
|
||||||
|
* 无前端代码或极少代码
|
||||||
|
* 降低前端开发技术难度
|
||||||
|
* 数据驱动
|
||||||
|
* 常用控件包装
|
||||||
|
* 纯json开发
|
||||||
|
|
||||||
|
## bricks概念
|
||||||
|
* 控件与控件继承
|
||||||
|
* 事件以及事件处理
|
||||||
|
* 控件嵌套和页面组装
|
||||||
|
|
||||||
|
### 控件与控件继承
|
||||||
|
bricks采用控件这一概念来描述web GUI的显示部件,每个控件均映射到一个html
|
||||||
|
的标签类型的一个javascript类。每个控件均可以实例化,并可在页面显示。
|
||||||
|
控件分为:基本控件,容器控件。
|
||||||
|
|
||||||
|
* 基本控件
|
||||||
|
基本控件是一个原子控件,不能有子控件。
|
||||||
|
* 容器控件
|
||||||
|
容器控件可以有子控件,bricks通过在容器控件添加子控件,以及在子容器控件中
|
||||||
|
在添加子子控件的方式来构造复杂的web页面。
|
||||||
|
|
||||||
|
控件的详细介绍请参看[控件说明](widgets.md)
|
||||||
|
|
||||||
|
### 控件扩展
|
||||||
|
如果现有的控件没法满足系统要求,bricks支持控件扩展,控件扩展需遵守:
|
||||||
|
* 控件class继承自某一个控件的class
|
||||||
|
|
||||||
|
* 按照需求实现控件逻辑
|
||||||
|
|
||||||
|
* 在需要的地方用this.dispatch触发此控件的事件
|
||||||
|
|
||||||
|
假设需要扩展一个名字叫ExtContainer的控件
|
||||||
|
```
|
||||||
|
bricks.ExtContainer = class extends bricks.VBox {
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
/* 新控件的创建代码 */
|
||||||
|
}
|
||||||
|
......
|
||||||
|
/* 对象的其他方法,在需要的时候,在某个方法中,使用this.dispatch('new_event', data)方法引发事件 */
|
||||||
|
}
|
||||||
|
bricks.register('ExtContainer', bricks.ExtContainer); /* 注册新控件 */
|
||||||
|
```
|
||||||
|
新控件的使用,example.ui
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"widgettype":"ExtContainer",
|
||||||
|
"options":{
|
||||||
|
....
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"new_event",
|
||||||
|
"actiontype":"urlwidget",
|
||||||
|
"target":"some_container",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('./some_ui.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 事件以及事件处理
|
||||||
|
每个控件都能触发所映射dom元素的事件,以及控件js类的成员函数以及祖先类的
|
||||||
|
成员函数中dispatch出的事件
|
||||||
|
|
||||||
|
所以bricks控件的事件来源于两类,dom元素原生事件以及控件类中创造的事件。
|
||||||
|
两类事件处理方式相同。
|
||||||
|
|
||||||
|
### 控件表达形式
|
||||||
|
在服务器的后台,以json文件的形式表达控件,每个ui文件定义一个控件,
|
||||||
|
对于容器控件,可以在ui文件中的subwidgets子属性中为此控件添加子控件
|
||||||
|
|
||||||
|
#### id属性
|
||||||
|
字符串属性,定义控件的id,让控件可以用getWidgetById找到,如果不给定,系统会自动生成一个id
|
||||||
|
#### options属性
|
||||||
|
字典属性,创建控件时的选项,每个控件可接受的选项请参看控件选项说明
|
||||||
|
#### binds属性
|
||||||
|
数组属性,定义零到多个事件响应,每个bind字典需要遵守[事件](event.md)要求
|
||||||
|
#### 容器控件特有属性
|
||||||
|
##### subwidgets
|
||||||
|
数组属性,定义容器控件的子控件,每个元素定义一个子控件,子控件遵守控件的数据要素要求
|
||||||
|
|
||||||
|
## 开发
|
||||||
|
使用存放在服务器后台的.ui后缀的json格式文件来开发,每个.ui文件定义一个控件, 支持基本控件和容器空间。
|
||||||
|
|
||||||
|
关于如何书写ui文件请参考[UI文件格式](descjson.md)
|
||||||
|
|
||||||
|
## 调试
|
||||||
|
ui文件可以直接调试,如在服务器根目录下的test目录下有一个hello.ui文件,
|
||||||
|
就可以在浏览器中用url:https://sername/test/hello.ui调试
|
||||||
|
|
||||||
92
docs/ai/button.md
Normal file
92
docs/ai/button.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# Button
|
||||||
|
|
||||||
|
按钮控件(Button)是 Bricks.js 框架中用于触发用户交互行为的**普通控件**,继承自 `bricks.Layout`。它通常用于提交表单、打开弹窗、执行脚本或导航等操作。Button 支持图标、文本标签、自定义样式以及事件绑定,适用于各种 UI 场景。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`target_clicked(event)`**
|
||||||
|
内部方法,当按钮被点击时触发,阻止事件冒泡并派发 `click` 事件,同时处理配置的 `action` 行为。
|
||||||
|
|
||||||
|
- **`create()`**
|
||||||
|
创建底层 DOM 元素(`<button>` 标签),由框架自动调用。
|
||||||
|
|
||||||
|
- **`opts_setup()`**
|
||||||
|
初始化按钮内容:根据 `opts.icon` 和 `opts.label` 创建图标和文本子控件,并添加到布局中。
|
||||||
|
|
||||||
|
- **`add_widget(widget)`**
|
||||||
|
继承自父类,用于向按钮内部添加子控件(如 Icon 或 Text)。
|
||||||
|
|
||||||
|
- **`bind(event, handler)`**
|
||||||
|
绑定自定义事件处理器(例如 `'click'` 事件)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`click`**
|
||||||
|
当按钮被用户点击时触发。可通过 `binds` 配置监听此事件,并执行相应动作(如调用方法、跳转页面、发送请求等)。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "btn_submit", // 控件唯一标识
|
||||||
|
"widgettype": "Button", // 控件类型:Button
|
||||||
|
"options": {
|
||||||
|
"name": "btn_submit", // 按钮名称(用于 DOM ID 设置)
|
||||||
|
"label": "Submit", // 显示的文字标签(支持 i18n 国际化)
|
||||||
|
"icon": "icons/submit.png", // 图标路径(可选)
|
||||||
|
"color": "#ffffff", // 文字颜色
|
||||||
|
"bgcolor": "#007BFF", // 背景色
|
||||||
|
"item_rate": 1.2, // 图标与文字的比例系数
|
||||||
|
"orientation": "horizontal", // 布局方向:horizontal(图标在左) / vertical
|
||||||
|
"css": "custom-btn", // 自定义 CSS 类名
|
||||||
|
"nonepack": false, // 是否去除默认 padding 和边框
|
||||||
|
"action": {
|
||||||
|
"actiontype": "method", // 点击后执行的动作类型
|
||||||
|
"wid": "form_main", // 目标组件 ID
|
||||||
|
"method": "submit", // 调用的方法名
|
||||||
|
"params": {} // 方法参数
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method", // 动作类型:调用方法
|
||||||
|
"wid": "btn_submit", // 触发组件 ID
|
||||||
|
"event": "click", // 监听事件:点击
|
||||||
|
"target": "form_main", // 目标组件 ID
|
||||||
|
"method": "validateAndSubmit", // 执行方法
|
||||||
|
"params": {
|
||||||
|
"showLoading": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script", // 执行脚本
|
||||||
|
"wid": "btn_submit",
|
||||||
|
"event": "click",
|
||||||
|
"target": "", // script 类型无需 target
|
||||||
|
"script": "console.log('Button clicked:', params);",
|
||||||
|
"params": {
|
||||||
|
"message": "Hello from Button!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event", // 派发自定义事件
|
||||||
|
"wid": "btn_submit",
|
||||||
|
"event": "click",
|
||||||
|
"target": "Popup", // 向弹窗系统派发事件
|
||||||
|
"dispatch_event": "open_dialog",
|
||||||
|
"params": {
|
||||||
|
"dialogId": "confirm_save"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
>
|
||||||
|
> - `widgettype: "Button"` 表示使用已注册的 Button 控件。
|
||||||
|
> - `options` 中的 `action` 是按钮内置的行为配置,也可通过 `binds` 实现更复杂的逻辑。
|
||||||
|
> - `binds` 数组允许一个按钮绑定多个不同类型的响应动作(方法调用、脚本执行、事件派发等)。
|
||||||
|
> - 图标和文本会自动按 `orientation` 排列,`item_rate` 控制大小比例。
|
||||||
|
> - 使用 `i18n: true`(隐式支持)时,`label` 可以从语言包中读取多语言值。
|
||||||
|
> - `nonepack: true` 可用于创建无边距/无背景的纯净按钮,适合嵌入工具栏等场景。
|
||||||
97
docs/ai/camera.md
Normal file
97
docs/ai/camera.md
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# Camera
|
||||||
|
|
||||||
|
**控件用途**:
|
||||||
|
`Camera` 是一个用于调用用户设备摄像头的弹窗式控件,支持拍照和视频录制功能。它继承自 `Popup` 控件,属于**容器控件**,可包含子控件(如按钮、图像显示区域等),并通过内置逻辑实现媒体流的获取与处理。
|
||||||
|
|
||||||
|
- **类型**:容器控件(继承自 `bricks.Popup`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 描述 |
|
||||||
|
|--------|------|
|
||||||
|
| `startCamera(vpos)` | 异步启动摄像头,使用指定的视频设备索引(vpos)初始化媒体流并开始预览。 |
|
||||||
|
| `show_picture()` | 在画布上绘制当前视频帧,并实时更新到 `Image` 子控件中,实现取景器效果。 |
|
||||||
|
| `switch_camera(btn, event)` | 切换当前使用的摄像头(前后置或多个摄像头之间切换)。 |
|
||||||
|
| `take_picture(event)` | 拍摄当前画面并触发 `shot` 事件,传出图片的 Data URL。 |
|
||||||
|
| `switch_recording()` | 切换录制状态:开始或停止视频录制。 |
|
||||||
|
| `videorecorder_start()` | 启动 `MediaRecorder` 开始录制视频,保存数据片段。 |
|
||||||
|
| `videorecorder_stop()` | 停止视频录制,并生成 Blob 文件,派发 `recorded` 事件。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 参数 |
|
||||||
|
|--------|---------|------|
|
||||||
|
| `shot` | 拍照完成时触发 | `dataurl`: 当前截图的 JPEG 格式 Data URL 字符串 |
|
||||||
|
| `recorded` | 视频录制结束时触发 | `file`: 生成的 WebM 格式视频文件对象(File) |
|
||||||
|
| `dismiss` | 用户点击取消按钮关闭弹窗时触发 | 无参数(由 `del_btn` 的 click 绑定触发) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "camera_popup",
|
||||||
|
"widgettype": "Camera",
|
||||||
|
"options": {
|
||||||
|
"type": "picture", // 可选 'picture' 或 'recorder'
|
||||||
|
"fps": 60, // 帧率,默认为60
|
||||||
|
"title": "拍照/录像" // 弹窗标题
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "shot_btn", // 实际ID会自动生成,此处仅为示意
|
||||||
|
"event": "shot",
|
||||||
|
"target": "image_preview",
|
||||||
|
"dispatch_event": "setValue",
|
||||||
|
"rtdata": {
|
||||||
|
"value": "{data}" // 动态插入拍摄的图片URL
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "camera_popup",
|
||||||
|
"event": "recorded",
|
||||||
|
"target": "video_list",
|
||||||
|
"dispatch_event": "addItem",
|
||||||
|
"rtdata": {
|
||||||
|
"item": {
|
||||||
|
"name": "录制视频",
|
||||||
|
"url": "{data}",
|
||||||
|
"type": "video/webm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "del_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "camera_popup",
|
||||||
|
"method": "dismiss"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subwidgets": [
|
||||||
|
// Camera 自身管理子控件,一般无需手动定义 subwidgets
|
||||||
|
// 内部已构建:HBox(按钮栏)、Filler(图像展示区)、Svg按钮等
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明**:
|
||||||
|
> - `widgettype: "Camera"` 表示使用注册的 Camera 控件。
|
||||||
|
> - `options.type` 决定是拍照模式还是录像模式:
|
||||||
|
> - `"picture"`:显示拍照按钮,点击后触发 `shot` 事件;
|
||||||
|
> - `"recorder"`:显示录制控制按钮,支持开始/停止录制,触发 `recorded` 事件。
|
||||||
|
> - `binds` 中通过事件绑定将拍摄结果传递给其他控件进行后续处理(如显示或上传)。
|
||||||
|
> - `target` 支持指向其他控件 ID,实现组件间通信。
|
||||||
|
> - 使用 `{data}` 占位符可在运行时自动替换为事件携带的数据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
💡 **提示**:
|
||||||
|
该控件依赖全局 `bricks.app` 提供的 `start_camera(vpos)` 方法和 `video_devices` 设备列表,需确保平台支持 getUserMedia 并已正确初始化媒体权限。
|
||||||
151
docs/ai/cols.md
Normal file
151
docs/ai/cols.md
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
# Cols
|
||||||
|
|
||||||
|
**用途**:`Cols` 是一个用于展示分页滚动数据列表的容器控件,适用于移动端或响应式布局中以卡片形式展示多条记录(如新闻、商品、消息等)。它支持无限滚动加载前一页和后一页数据,具备自动触发加载机制,并可通过点击选中某一条记录。
|
||||||
|
|
||||||
|
**类型**:容器控件,继承自 `bricks.VBox`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `load_first_page(params)` | 首次加载数据,可传入额外参数 `params` 合并到请求中。若配置了 `data_url`,则从服务器拉取数据;否则使用本地数据 `this.data`。 |
|
||||||
|
| `load_previous_page()` | 加载上一页数据,当用户滚动到顶部时自动触发(绑定在 `min_threshold` 事件上)。 |
|
||||||
|
| `load_next_page()` | 加载下一页数据,当用户滚动到底部时自动触发(绑定在 `max_threshold` 事件上)。 |
|
||||||
|
| `dataHandle(d)` | 处理返回的数据 `d`,将每条记录渲染为一个子控件并插入主容器 `main` 中,支持逆序插入(用于上翻页)。 |
|
||||||
|
| `delete_page(page)` | 删除指定页码的所有 DOM 元素及其对应的控件实例,用于清理不再需要的页面内容。 |
|
||||||
|
| `create_main_widget()` | 创建内部显示区域的主控件 `DynamicColumn`,用于管理列数和响应式布局。 |
|
||||||
|
| `show_with_data(data)` | 直接传入静态数据进行展示,不依赖远程 URL,适合临时数据显示。 |
|
||||||
|
| `command_handle(event)` | 工具栏命令处理函数,派发工具栏按钮对应的事件名称。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发条件 | 携带数据 |
|
||||||
|
|--------|----------|---------|
|
||||||
|
| `record_click` | 用户点击某一条记录项时触发 | 当前记录的数据对象(`rw.user_data`) |
|
||||||
|
| `command` | 工具栏按钮被点击时(由 `Toolbar` 控件发出),通过 `command_handle` 转发为同名事件 | 按钮定义中的 `name` 参数 |
|
||||||
|
|
||||||
|
> 注:`min_threshold` 和 `max_threshold` 是 `VScrollPanel` 提供的滚动边界事件,分别表示滚动到顶部和底部,用于驱动分页加载。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "cols_example",
|
||||||
|
"widgettype": "Cols",
|
||||||
|
"options": {
|
||||||
|
// 数据源地址,返回符合 PageDataLoader 格式的 JSON
|
||||||
|
"data_url": "/api/news/list",
|
||||||
|
|
||||||
|
// 请求参数
|
||||||
|
"data_params": {
|
||||||
|
"category": "tech",
|
||||||
|
"page_size": 10
|
||||||
|
},
|
||||||
|
|
||||||
|
// HTTP 方法,默认 GET
|
||||||
|
"data_method": "GET",
|
||||||
|
|
||||||
|
// 每页显示行数
|
||||||
|
"page_rows": 10,
|
||||||
|
|
||||||
|
// 缓存页数限制
|
||||||
|
"cache_limit": 5,
|
||||||
|
|
||||||
|
// 列宽设置(百分比)
|
||||||
|
"col_cwidth": "48%",
|
||||||
|
|
||||||
|
// 移动端列数
|
||||||
|
"mobile_cols": 1,
|
||||||
|
|
||||||
|
// 标题文本(支持国际化)
|
||||||
|
"title": "最新资讯",
|
||||||
|
"i18n": true,
|
||||||
|
|
||||||
|
// 描述信息(Markdown 支持)
|
||||||
|
"description": "这里是科技类新闻列表",
|
||||||
|
|
||||||
|
// 工具栏定义
|
||||||
|
"toolbar": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"text": "刷新",
|
||||||
|
"name": "refresh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"text": "新增",
|
||||||
|
"name": "add_new"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 每条记录的视图模板
|
||||||
|
"record_view": {
|
||||||
|
"widgettype": "CardWidget",
|
||||||
|
"options": {
|
||||||
|
"title": "{title}", // 动态字段替换
|
||||||
|
"subtitle": "发布时间: {ctime}",
|
||||||
|
"content": "{summary}",
|
||||||
|
"thumbnail": "{image_url}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 绑定事件
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "cols_example",
|
||||||
|
"event": "record_click",
|
||||||
|
"target": "detail_panel",
|
||||||
|
"rtdata": {
|
||||||
|
"action": "show_detail"
|
||||||
|
},
|
||||||
|
"dataparams": {
|
||||||
|
"source_event": "record_click"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "cols_example",
|
||||||
|
"event": "refresh",
|
||||||
|
"target": "cols_example",
|
||||||
|
"method": "load_first_page",
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "cols_example",
|
||||||
|
"event": "add_new",
|
||||||
|
"target": "Popup",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/forms/news_edit.ui",
|
||||||
|
"method": "GET",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ 注释说明:
|
||||||
|
|
||||||
|
- `"data_url"`:服务端接口路径,返回格式需包含 `rows`, `page`, `pos_rate` 等字段。
|
||||||
|
- `"record_view"`:定义每个数据项如何渲染成 UI 控件,支持字段插值 `{field}`。
|
||||||
|
- `"binds"`:
|
||||||
|
- 当用户点击某条记录时,派发 `record_click` 事件,通知 `detail_panel` 显示详情。
|
||||||
|
- 工具栏“刷新”按钮重新加载第一页数据。
|
||||||
|
- “新增”按钮打开弹窗(Popup),加载 `/forms/news_edit.ui` 表单界面。
|
||||||
|
- `VScrollPanel` 自动监听滚动位置,在接近边界时调用 `load_previous_page` / `load_next_page` 实现懒加载。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 💡 **提示**:`Cols` 特别适合构建类似微博、朋友圈、电商商品列表等需要长列表无限滚动的场景,结合 `PageDataLoader` 实现高效内存管理和数据缓存。
|
||||||
81
docs/ai/conform.md
Normal file
81
docs/ai/conform.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# Conform
|
||||||
|
|
||||||
|
控件用于在用户执行关键操作前弹出确认对话框,提供“确认”和“取消”两个选项。属于**容器控件**,继承自 `bricks.PopupWindow`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `constructor(opts)`
|
||||||
|
构造函数,接收配置参数 `opts`,自动设置超时为0、自动打开,并调用父类构造函数初始化弹窗。
|
||||||
|
|
||||||
|
- `create_conform()`
|
||||||
|
创建整体布局结构,包含消息区域和工具栏。
|
||||||
|
|
||||||
|
- `create_message(widget)`
|
||||||
|
在指定容器中创建消息显示区域,使用 `Text` 控件展示带换行的消息内容,支持国际化(i18n)。
|
||||||
|
|
||||||
|
- `create_toolbar(widget)`
|
||||||
|
创建底部按钮栏(`IconTextBar`),包含“确认”和“取消”按钮,可自定义图标与标签。
|
||||||
|
|
||||||
|
- `conform_hndl(event)`
|
||||||
|
点击“确认”按钮时触发,关闭弹窗并派发 `conformed` 事件。
|
||||||
|
|
||||||
|
- `discard_hndl(event)`
|
||||||
|
点击“取消”按钮时触发,关闭弹窗并派发 `cancelled` 事件。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发条件 | 携带数据 |
|
||||||
|
|--------------|------------------------|----------|
|
||||||
|
| `conformed` | 用户点击“确认”按钮 | 无 |
|
||||||
|
| `cancelled` | 用户点击“取消”按钮 | 无 |
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "confirm_delete",
|
||||||
|
"widgettype": "Conform",
|
||||||
|
"options": {
|
||||||
|
"message": "Are you sure you want to delete this item?", // 要显示的提示信息
|
||||||
|
"i18n": true, // 支持国际化
|
||||||
|
"conform": { // 自定义“确认”按钮
|
||||||
|
"label": "Delete",
|
||||||
|
"icon": "imgs/delete.svg"
|
||||||
|
},
|
||||||
|
"discard": { // 自定义“取消”按钮
|
||||||
|
"label": "Keep",
|
||||||
|
"icon": "imgs/keep.svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "confirm_delete",
|
||||||
|
"event": "conformed",
|
||||||
|
"target": "data_manager",
|
||||||
|
"method": "deleteItem",
|
||||||
|
"params": {
|
||||||
|
"itemId": "{#input_form.getValue('id')}" // 动态获取表单中的ID值
|
||||||
|
},
|
||||||
|
"description": "当用户确认删除时,调用数据管理器删除对应项目"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "confirm_delete",
|
||||||
|
"event": "cancelled",
|
||||||
|
"script": "console.log('Delete operation was cancelled by user.');",
|
||||||
|
"description": "用户取消删除操作时输出日志"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释说明:
|
||||||
|
|
||||||
|
- `"widgettype": "Conform"`:必须确保该控件已在 bricks 框架中注册。
|
||||||
|
- `options.message`:支持静态文本或 i18n 键名,若启用 `i18n: true`,会自动翻译。
|
||||||
|
- `conform` 和 `discard` 字段是可选的,用于覆盖默认按钮样式与行为。
|
||||||
|
- `binds` 中通过监听 `conformed` 和 `cancelled` 事件实现后续逻辑处理。
|
||||||
|
- 使用 `{#...}` 表达式可在运行时动态求值,如从其他控件获取数据。
|
||||||
|
|
||||||
|
> 💡 提示:此控件常用于删除、退出、覆盖等需要二次确认的操作场景,提升用户体验与安全性。
|
||||||
145
docs/ai/continueaudio.md
Normal file
145
docs/ai/continueaudio.md
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# ContinueAudioPlayer
|
||||||
|
|
||||||
|
该控件是一个**容器控件**,继承自 `bricks.VBox`,用于在浏览器中连续播放通过 WebSocket 或 Base64 编码传输的音频数据。它基于 Web Audio API 实现高精度、低延迟的音频播放控制,支持暂停、恢复、重新开始、音量调节和静音功能。适用于语音播报、实时通信、在线教育等需要无缝播放多个音频片段的场景。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`initAudioContext()`**
|
||||||
|
初始化 Web Audio API 的上下文(AudioContext)和增益节点(GainNode),为后续音频播放做准备。
|
||||||
|
|
||||||
|
- **`base64ToArrayBuffer(base64)`**
|
||||||
|
将 Base64 编码的音频字符串转换为 ArrayBuffer,供 `decodeAudioData` 使用。
|
||||||
|
|
||||||
|
- **`handleAudioTrack(arrayBuffer)`**
|
||||||
|
解码并播放传入的音频数据(ArrayBuffer),自动管理播放时间线,确保多个音频连续播放不重叠。
|
||||||
|
|
||||||
|
- **`pauseAudio()`**
|
||||||
|
暂停当前播放的音频(实际是挂起 AudioContext)。
|
||||||
|
|
||||||
|
- **`resumeAudio()`**
|
||||||
|
恢复被暂停的音频播放。
|
||||||
|
|
||||||
|
- **`restart()`**
|
||||||
|
关闭当前 AudioContext 并重新初始化,从头开始播放。
|
||||||
|
|
||||||
|
- **`setVolume(value)`**
|
||||||
|
设置音量(0.0 ~ 1.0),自动更新增益节点,并触发 `onVolumeChange` 事件。
|
||||||
|
|
||||||
|
- **`toggleMute()`**
|
||||||
|
切换静音状态,同时更新增益值并发出音量变化事件。
|
||||||
|
|
||||||
|
- **`emit(eventName, ...args)`**
|
||||||
|
触发配置中的回调函数,如 `onStart`、`onEnd` 等。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
这些事件可通过 `options` 配置传入回调函数,在特定时刻执行逻辑:
|
||||||
|
|
||||||
|
- **`onStart`**:当一个音频轨道开始播放时触发。
|
||||||
|
- **`onEnd`**:当一个音频轨道播放结束后触发。
|
||||||
|
- **`onPause`**:调用 `pauseAudio` 成功后触发。
|
||||||
|
- **`onResume`**:调用 `resumeAudio` 成功后触发。
|
||||||
|
- **`onVolumeChange`**:音量或静音状态改变时触发,参数为当前有效音量(静音时为 0)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "audioPlayerContainer",
|
||||||
|
"widgettype": "ContinueAudioPlayer",
|
||||||
|
"options": {
|
||||||
|
"ws_url": "wss://example.com/audio-stream", // 可选:WebSocket 地址(若使用流式接收)
|
||||||
|
"onStart": "function() { console.log('音频开始播放'); }",
|
||||||
|
"onEnd": "function() { console.log('音频播放结束'); }",
|
||||||
|
"onPause": "function() { bricks.getWidget('playBtn').setValue('▶️ 播放'); }",
|
||||||
|
"onResume": "function() { bricks.getWidget('playBtn').setValue('⏸️ 暂停'); }",
|
||||||
|
"onVolumeChange": "function(vol) { bricks.getWidget('volumeSlider').setValue(vol); }"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "controlBar",
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "playBtn",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"value": "▶️ 播放",
|
||||||
|
"onClick": "function() { var player = bricks.getWidget('audioPlayerContainer'); if (player.audioContext.state === 'running') { player.pauseAudio(); } else { player.resumeAudio(); } }"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "restartBtn",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"value": "🔁 重新开始",
|
||||||
|
"onClick": "function() { bricks.getWidget('audioPlayerContainer').restart(); }"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "muteBtn",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"value": "🔊 静音",
|
||||||
|
"onClick": "function() { var player = bricks.getWidget('audioPlayerContainer'); player.toggleMute(); this.setValue(player.muted ? '🔇 取消静音' : '🔊 静音'); }"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volumeSlider",
|
||||||
|
"widgettype": "Slider",
|
||||||
|
"options": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1,
|
||||||
|
"step": 0.01,
|
||||||
|
"value": 1,
|
||||||
|
"onChange": "function(val) { bricks.getWidget('audioPlayerContainer').setVolume(val); }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "externalStartTrigger",
|
||||||
|
"event": "click",
|
||||||
|
"target": "audioPlayerContainer",
|
||||||
|
"method": "resumeAudio",
|
||||||
|
"conform": {
|
||||||
|
"title": "确认播放",
|
||||||
|
"message": "确定要开始播放音频吗?",
|
||||||
|
"confirmButtonText": "确定",
|
||||||
|
"cancelButtonText": "取消"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "dataReceiver",
|
||||||
|
"event": "audioDataReady",
|
||||||
|
"target": "audioPlayerContainer",
|
||||||
|
"datascript": "return base64EncodedAudioChunk;", // 假设外部脚本提供了此变量
|
||||||
|
"script": "const buf = widget.base64ToArrayBuffer(rtdata); widget.handleAudioTrack(buf);"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
>
|
||||||
|
> - `ContinueAudioPlayer` 本身作为容器,包含一组控制按钮(播放/暂停、重启、静音、音量滑块)。
|
||||||
|
> - `binds` 中定义了两个行为:
|
||||||
|
> 1. 点击外部元素 `externalStartTrigger` 时,调用播放器的 `resumeAudio` 方法,带确认弹窗。
|
||||||
|
> 2. 当 `dataReceiver` 组件触发 `audioDataReady` 事件时,执行脚本将 Base64 数据转为 ArrayBuffer 并交给播放器处理。
|
||||||
|
> - 所有 UI 控件通过 ID 获取实例并与 `ContinueAudioPlayer` 实例交互。
|
||||||
|
> - 回调函数使用字符串形式的 `function(){}` 写法,符合 Bricks.js 对 options 中函数的序列化要求。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
💡 **提示:**
|
||||||
|
要实现真正的“持续”播放,需保证不断向 `handleAudioTrack` 方法传入新的音频数据块(ArrayBuffer)。可结合 WebSocket 接收流式音频并解码推送至此控件。
|
||||||
131
docs/ai/countdown.md
Normal file
131
docs/ai/countdown.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# TimePassed
|
||||||
|
|
||||||
|
用于显示从开始计时起经过的时间(格式为 `hh:mm:ss`),是一个容器控件,继承自 `bricks.VBox`。该控件每秒自动更新一次时间显示,适用于需要展示运行时长的场景,如计时器、任务耗时统计等。
|
||||||
|
|
||||||
|
**类型**:容器控件(继承自 `bricks.VBox`)
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **start()**
|
||||||
|
开始计时,启动一个周期性任务,每秒调用一次 `add_one_second()` 方法以递增时间并更新界面。
|
||||||
|
|
||||||
|
- **stop()**
|
||||||
|
停止计时,取消当前正在执行的周期性任务,防止继续更新时间。
|
||||||
|
|
||||||
|
- **add_one_second()**
|
||||||
|
内部私有方法,用于将内部秒数加1,并格式化后更新到子控件 `Text` 中;之后再次调度自身,实现循环计时。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件派发。仅依赖父类 `VBox` 的基础事件能力。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "time_passed_widget",
|
||||||
|
"widgettype": "TimePassed",
|
||||||
|
"options": {
|
||||||
|
// 可选参数,例如可以扩展 text_rate 控制文本刷新频率
|
||||||
|
// "text_rate": 1000 // 示例:表示文本更新速率(毫秒)
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_start_timer",
|
||||||
|
"event": "click",
|
||||||
|
"target": "time_passed_widget",
|
||||||
|
"method": "start",
|
||||||
|
"rtdata": {},
|
||||||
|
"conform": null,
|
||||||
|
"description": "当点击“开始”按钮时,启动计时器"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_stop_timer",
|
||||||
|
"event": "click",
|
||||||
|
"target": "time_passed_widget",
|
||||||
|
"method": "stop",
|
||||||
|
"rtdata": {},
|
||||||
|
"conform": null,
|
||||||
|
"description": "当点击“停止”按钮时,停止计时器"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **说明**:
|
||||||
|
> - `TimePassed` 是一个简单的计时显示器,初始化时时间为 `00:00:00`。
|
||||||
|
> - 使用 `start()` 启动后,会持续递增时间直到被 `stop()` 停止。
|
||||||
|
> - 子控件中包含一个 `Text` 控件用于显示时间字符串。
|
||||||
|
> - 时间格式通过全局函数 `bricks.formatTime(seconds)` 统一处理,确保格式一致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Countdown
|
||||||
|
|
||||||
|
倒计时控件,用于从指定时间开始倒数至零,结束后触发 `timeout` 事件。它是一个容器控件,继承自 `bricks.VBox`,内部使用一个 `Text` 控件显示剩余时间。
|
||||||
|
|
||||||
|
**类型**:容器控件(继承自 `bricks.VBox`)
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **start()**
|
||||||
|
启动倒计时,首次调用 `time_down_second()` 并设置1秒延迟执行,开始递减过程。
|
||||||
|
|
||||||
|
- **time_down_second()**
|
||||||
|
内部私有方法:每次被调用时将剩余秒数减1,重新格式化时间并更新显示;若时间归零,则派发 `timeout` 事件并终止倒计时。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **timeout**
|
||||||
|
当倒计时结束(即时间到达 `00:00:00`)时自动触发。可用于绑定后续操作,如弹窗提醒、跳转页面或播放提示音。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "countdown_timer",
|
||||||
|
"widgettype": "Countdown",
|
||||||
|
"options": {
|
||||||
|
"limit_time": "00:05:00", // 倒计时总时长:5分钟
|
||||||
|
"text_rate": 1000 // 文本更新频率(可选,默认1秒刷新一次)
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_start_countdown",
|
||||||
|
"event": "click",
|
||||||
|
"target": "countdown_timer",
|
||||||
|
"method": "start",
|
||||||
|
"rtdata": {},
|
||||||
|
"description": "用户点击‘开始倒计时’按钮时启动倒计时"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "countdown_timer",
|
||||||
|
"event": "timeout",
|
||||||
|
"target": "Popup",
|
||||||
|
"dispatch_event": "showMessage",
|
||||||
|
"params": {
|
||||||
|
"title": "倒计时结束",
|
||||||
|
"content": "您的5分钟倒计时已结束!",
|
||||||
|
"level": "info"
|
||||||
|
},
|
||||||
|
"description": "倒计时结束后弹出提示框通知用户"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **说明**:
|
||||||
|
> - `limit_time` 必须是 `"hh:mm:ss"` 格式的字符串,支持部分格式如 `"30"`(表示30秒)、`"2:30"`(表示2分30秒)等。
|
||||||
|
> - 倒计时精度为1秒,使用 `schedule_once(..., 1)` 实现定时。
|
||||||
|
> - 当时间耗尽时,通过 `this.dispatch('timeout')` 触发事件,外部可通过 `binds` 监听此事件进行响应。
|
||||||
|
> - 此控件适合用于限时答题、会议提醒、休息倒计等功能模块。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
📌 **备注**:两个控件均已通过 `bricks.Factory.register()` 注册,可在 `.ui` 文件中直接作为 `widgettype` 使用。
|
||||||
208
docs/ai/datagrid.md
Normal file
208
docs/ai/datagrid.md
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
# DataGrid
|
||||||
|
|
||||||
|
DataGrid 是一个用于展示结构化数据的容器控件,支持分页加载、冻结列、行选择、工具栏集成等功能。它是 `bricks` 框架中用于替代传统表格(table)的高级布局控件,继承自 `VBox`,属于**容器控件**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 描述 |
|
||||||
|
|--------|------|
|
||||||
|
| `add_row(data, index)` | 向表格中添加一行数据,可指定插入位置(index)。 |
|
||||||
|
| `add_rows(records, direction)` | 批量添加多行记录,支持从顶部或底部添加(direction: 'up'/'down')。 |
|
||||||
|
| `clear_data()` | 清空所有数据行,包括冻结区和正常区的内容。 |
|
||||||
|
| `loadData(params)` | 重新加载数据,传入参数给后端请求。 |
|
||||||
|
| `create_header()` | 根据字段定义创建表头。 |
|
||||||
|
| `create_parts()` | 创建整体布局结构:冻结列区域、主内容区域、滚动同步等。 |
|
||||||
|
| `coscroll(event)` | 实现两个垂直滚动面板之间的同步滚动(用于冻结列与主体列对齐)。 |
|
||||||
|
| `miniform_input(event)` | 响应搜索表单输入事件,触发数据重载。 |
|
||||||
|
| `command_handle(event)` | 处理来自工具栏的命令事件(如“新增”、“删除”等),需开发者扩展实现。 |
|
||||||
|
| `del_old_rows(cnt, direction)` | 删除旧的行(从开头或结尾),用于缓冲加载策略。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 参数说明 |
|
||||||
|
|-------|---------|----------|
|
||||||
|
| `row_click` | 用户点击某一行时触发 | 回调参数为被点击的 `Row` 实例对象,可通过其 `.data` 获取原始数据 |
|
||||||
|
| `min_threshold` | 滚动接近顶部边界时触发 | 通常用于加载上一页数据 |
|
||||||
|
| `max_threshold` | 滚动接近底部边界时触发 | 通常用于加载下一页数据 |
|
||||||
|
| `scroll` | 滚动发生时触发 | 用于实现双列滚动同步 |
|
||||||
|
|
||||||
|
> 注:这些事件通过 `bind()` 进行监听,例如绑定到 `normal_body` 或 `freeze_body` 的滚动行为。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "my_datagrid",
|
||||||
|
"widgettype": "DataGrid",
|
||||||
|
"options": {
|
||||||
|
// 数据源配置
|
||||||
|
"dataurl": "/api/users", // 从该 URL 异步获取数据
|
||||||
|
"method": "GET", // 请求方式,默认为 GET
|
||||||
|
"params": { "page_size": 80 }, // 请求参数
|
||||||
|
|
||||||
|
// 显示配置
|
||||||
|
"title": "用户列表", // 表格标题(支持 i18n)
|
||||||
|
"description": "所有注册用户的详细信息", // 描述文本
|
||||||
|
"show_info": true, // 是否显示信息栏
|
||||||
|
"row_height": "40px", // 每行高度
|
||||||
|
"header_css": "grid_header", // 表头样式类名
|
||||||
|
"body_css": "grid_body", // 表体样式类名
|
||||||
|
|
||||||
|
// 功能开关
|
||||||
|
"check": false, // 是否显示复选框列
|
||||||
|
"lineno": true, // 是否显示行号列
|
||||||
|
|
||||||
|
// 工具栏与搜索
|
||||||
|
"miniform": {
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "keyword",
|
||||||
|
"uitype": "text",
|
||||||
|
"label": "搜索关键词",
|
||||||
|
"i18n": true,
|
||||||
|
"uioptions": {
|
||||||
|
"placeholder": "请输入用户名..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"uitype": "select",
|
||||||
|
"label": "状态",
|
||||||
|
"i18n": true,
|
||||||
|
"uioptions": {
|
||||||
|
"options": [
|
||||||
|
{ "label": "全部", "value": "" },
|
||||||
|
{ "label": "启用", "value": "active" },
|
||||||
|
{ "label": "禁用", "value": "inactive" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"toolbar": {
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"name": "add_user",
|
||||||
|
"label": "新增用户",
|
||||||
|
"icon": "add",
|
||||||
|
"action": {
|
||||||
|
"actiontype": "newwindow",
|
||||||
|
"target": "/user/add",
|
||||||
|
"mode": "popup",
|
||||||
|
"width": 800,
|
||||||
|
"height": 600
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "refresh",
|
||||||
|
"label": "刷新",
|
||||||
|
"icon": "refresh",
|
||||||
|
"action": {
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "my_datagrid",
|
||||||
|
"method": "loadData",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 字段定义
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"label": "用户名",
|
||||||
|
"uitype": "text",
|
||||||
|
"width": 120,
|
||||||
|
"freeze": true, // 冻结此列(固定左侧)
|
||||||
|
"i18n": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"label": "邮箱",
|
||||||
|
"uitype": "text",
|
||||||
|
"width": 180,
|
||||||
|
"i18n": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"label": "状态",
|
||||||
|
"uitype": "label",
|
||||||
|
"width": 100,
|
||||||
|
"uioptions": {
|
||||||
|
"css_map": {
|
||||||
|
"active": "success",
|
||||||
|
"inactive": "danger"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "last_login",
|
||||||
|
"label": "最后登录时间",
|
||||||
|
"uitype": "datetime",
|
||||||
|
"width": 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "action",
|
||||||
|
"label": "操作",
|
||||||
|
"uitype": "button",
|
||||||
|
"width": 100,
|
||||||
|
"icon": "edit",
|
||||||
|
"action": {
|
||||||
|
"actiontype": "newwindow",
|
||||||
|
"target": "/user/edit?id={id}",
|
||||||
|
"mode": "popup",
|
||||||
|
"width": 900,
|
||||||
|
"height": 700
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "my_datagrid",
|
||||||
|
"event": "row_click",
|
||||||
|
"target": "detail_panel",
|
||||||
|
"dispatch_event": "update_detail",
|
||||||
|
"params": {
|
||||||
|
"source": "my_datagrid"
|
||||||
|
},
|
||||||
|
"datawidget": "my_datagrid",
|
||||||
|
"datamethod": "getValue",
|
||||||
|
"dataparams": {},
|
||||||
|
"rtdata": {
|
||||||
|
"section": "user_profile"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "my_datagrid",
|
||||||
|
"event": "row_click",
|
||||||
|
"script": "console.log('用户点击了行:', params.row_data);",
|
||||||
|
"params": {
|
||||||
|
"row_data": "{source.getValue()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释说明:
|
||||||
|
|
||||||
|
- **`dataurl`**: 设置远程数据接口地址,框架会自动发起请求并渲染数据。
|
||||||
|
- **`miniform`**: 内置迷你搜索表单,用户输入后自动调用 `loadData()` 刷新数据。
|
||||||
|
- **`toolbar`**: 工具栏按钮支持弹窗、刷新等操作。
|
||||||
|
- **`fields[].freeze`**: 设为 `true` 可将列固定在左侧(常用于关键字段如 ID、姓名)。
|
||||||
|
- **`uitype: button`**: 在表格内嵌按钮,支持动态绑定动作(如编辑、删除)。
|
||||||
|
- **`binds`**:
|
||||||
|
- 第一条:当某行被点击时,向 `detail_panel` 控件派发 `update_detail` 自定义事件,传递当前行数据。
|
||||||
|
- 第二条:执行脚本输出调试日志,演示如何获取运行时数据。
|
||||||
|
|
||||||
|
> 💡 提示:结合 `BufferedDataLoader`,DataGrid 支持大数据量下的虚拟滚动与分页预加载,适用于成千上万条记录的场景。
|
||||||
152
docs/ai/datarow.md
Normal file
152
docs/ai/datarow.md
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
# DataRow
|
||||||
|
|
||||||
|
**用处**:`DataRow` 是一个用于展示数据行的容器控件,常用于表格或列表中的一行数据展示。支持表头与数据行的分别渲染,可配置字段显示、列宽、隐藏字段等,适用于构建数据浏览界面(如数据表格)。
|
||||||
|
|
||||||
|
**类型**:容器控件,继承自 `bricks.HBox`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `render_header()`
|
||||||
|
渲染表头部分(通常包含字段名),调用 `render(true)` 实现。
|
||||||
|
|
||||||
|
- `render_data()`
|
||||||
|
渲染数据内容部分,调用 `render(false)` 实现。
|
||||||
|
|
||||||
|
- `render(header: Boolean)`
|
||||||
|
根据 `header` 参数决定是否渲染为表头。若为 `true`,则显示字段标签;否则显示实际数据值。
|
||||||
|
|
||||||
|
- `renew(record: Object)`
|
||||||
|
更新当前行绑定的数据记录,并重新渲染数据部分。`record` 为新的数据对象。
|
||||||
|
|
||||||
|
- `get_check_state(e: Event)`
|
||||||
|
处理复选框状态变化事件,更新内部数据并派发 `check_changed` 事件。
|
||||||
|
|
||||||
|
- `build_toolbar(header: Boolean)`
|
||||||
|
构建工具栏(如操作图标按钮),根据 `header` 判断是否在表头区域创建空白占位。
|
||||||
|
|
||||||
|
- `my_dispatch(event_name: String)`
|
||||||
|
返回一个闭包函数,用于在工具栏按钮点击时派发对应事件。
|
||||||
|
|
||||||
|
- `_build_fields(header: Boolean, containerWidget: Widget)`
|
||||||
|
内部方法,遍历 `fields` 配置并生成对应的视图控件(如文本、图标等),添加到指定容器中。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `check_changed`
|
||||||
|
当复选框状态改变时触发,携带当前组件实例作为参数。可用于监听选中状态变更。
|
||||||
|
|
||||||
|
- 自定义工具栏事件(由 `toolbar.tools.name` 定义)
|
||||||
|
如 `edit`, `delete` 等,通过 `IconBar` 绑定后会派发同名事件,可通过 `binds` 监听处理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "data_row_001",
|
||||||
|
"widgettype": "DataRow",
|
||||||
|
"options": {
|
||||||
|
// 表格字段定义
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"label": "编号",
|
||||||
|
"uitype": "str",
|
||||||
|
"cwidth": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"label": "姓名",
|
||||||
|
"uitype": "str",
|
||||||
|
"cwidth": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"label": "状态",
|
||||||
|
"uitype": "label", // 使用标签控件显示
|
||||||
|
"cwidth": 8
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// 是否启用选择框
|
||||||
|
"checkField": "selected",
|
||||||
|
// 浏览器字段配置(控制列宽和隐藏)
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["internal_id"], // 不显示的字段
|
||||||
|
"cwidths": {
|
||||||
|
"status": 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 工具栏配置
|
||||||
|
"toolbar": {
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"name": "edit",
|
||||||
|
"icon": "pencil",
|
||||||
|
"tip": "编辑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "delete",
|
||||||
|
"icon": "trash",
|
||||||
|
"tip": "删除"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// 自定义样式
|
||||||
|
"css": "data-row-item",
|
||||||
|
"header_css": "header-row"
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
// 监听复选框变化
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "data_row_001",
|
||||||
|
"event": "check_changed",
|
||||||
|
"target": "data_grid_controller",
|
||||||
|
"dispatch_event": "row_selected",
|
||||||
|
"params": {
|
||||||
|
"rowid": "{data_row_001.getValue().id}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 编辑按钮点击
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "data_row_001",
|
||||||
|
"event": "edit", // 来自 IconBar 的事件
|
||||||
|
"target": "popup_manager",
|
||||||
|
"method": "openEditPopup",
|
||||||
|
"params": {
|
||||||
|
"recordId": "{data_row_001.getValue().id}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除按钮确认并执行
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "data_row_001",
|
||||||
|
"event": "delete",
|
||||||
|
"target": "data_row_001",
|
||||||
|
"dispatch_event": "confirm_delete",
|
||||||
|
"conform": {
|
||||||
|
"title": "确认删除",
|
||||||
|
"message": "确定要删除该条记录吗?",
|
||||||
|
"confirmButtonText": "删除",
|
||||||
|
"cancelButtonText": "取消"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
>
|
||||||
|
> - `fields` 定义了要展示的字段及其 UI 类型(`uitype`),框架会自动查找对应的 ViewBuilder 创建子控件。
|
||||||
|
> - `checkField` 启用行选择功能,会在最前插入一个复选框。
|
||||||
|
> - `toolbar.tools` 定义操作图标,每个 `name` 将作为事件名被 `DataRow` 派发。
|
||||||
|
> - `binds` 中通过 `event` 类型将内部事件转发给外部控制器处理。
|
||||||
|
> - `conform` 提供弹出确认对话框的能力,在危险操作前使用。
|
||||||
|
> - `{}` 中的表达式是 bricks 支持的运行时数据绑定语法,动态获取组件值。
|
||||||
129
docs/ai/dataviewer.md
Normal file
129
docs/ai/dataviewer.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
# DataViewer
|
||||||
|
|
||||||
|
DataViewer 是一个用于展示分页数据的容器控件,支持动态加载远程数据、滚动加载前后页、内置增删改查操作工具栏,并可通过子类扩展自定义记录视图。它继承自 `bricks.VBox`,属于**容器控件**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `render(params)` | 根据参数从服务器加载数据并渲染列表,默认会缓存请求参数避免重复加载 |
|
||||||
|
| `build_row(record, page, pos)` | 构建单条记录对应的控件,并插入到滚动面板中(可被重写) |
|
||||||
|
| `build_record_view(record)` | 创建每条数据的显示控件,子类需重写此方法以实现自定义 UI |
|
||||||
|
| `add_record()` | 打开新增记录弹窗 |
|
||||||
|
| `update_record(row)` | 打开编辑当前选中行记录的弹窗 |
|
||||||
|
| `clone_record(row)` | 克隆当前选中记录并打开新增表单 |
|
||||||
|
| `delete_record(row)` | 删除指定行记录,触发确认对话框 |
|
||||||
|
| `load_previous_page()` | 向上滚动时加载前一页数据(支持无限滚动) |
|
||||||
|
| `load_next_page()` | 向下滚动时加载后一页数据 |
|
||||||
|
| `command_event_handle(event)` | 处理工具栏按钮点击事件(如 add/update/delete 等) |
|
||||||
|
| `get_edit_fields()` | 获取可编辑字段列表,排除配置中设置的字段 |
|
||||||
|
| `get_hidefields()` | 获取隐藏字段(通常为过滤条件或上下文参数) |
|
||||||
|
| `build_add_form()` / `build_update_form(data)` / `build_clone_form(data)` | 分别构建新增、更新、克隆用的表单控件 |
|
||||||
|
| `build_window(icon, title, form)` | 创建弹出窗口包裹表单 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 携带数据 |
|
||||||
|
|--------|--------|---------|
|
||||||
|
| `row_check_changed` | 当某一行的选择状态发生变化时 | 被选中行的数据对象(`user_data`) |
|
||||||
|
| 自定义命令事件(如 `'add'`, `'update'` 等) | 用户点击工具栏按钮时 | 当前行数据(如有) |
|
||||||
|
|
||||||
|
> 注:这些事件可通过 `binds` 进行监听和处理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "dataviewer_main",
|
||||||
|
"widgettype": "DataViewer",
|
||||||
|
"options": {
|
||||||
|
// 数据源配置
|
||||||
|
"data_url": "/api/list_records", // 获取数据的接口地址
|
||||||
|
"data_method": "GET", // 请求方式
|
||||||
|
"data_params": { // 静态请求参数
|
||||||
|
"category": "news"
|
||||||
|
},
|
||||||
|
"page_rows": 20, // 每页加载多少条数据
|
||||||
|
"cache_limit": 5, // 最多缓存几个页面的数据
|
||||||
|
|
||||||
|
// 编辑功能配置(启用工具栏)
|
||||||
|
"editable": {
|
||||||
|
"add_icon": "imgs/add.svg",
|
||||||
|
"update_icon": "imgs/edit.svg",
|
||||||
|
"clone_icon": "imgs/clone.svg",
|
||||||
|
"delete_icon": "imgs/delete.svg",
|
||||||
|
"new_data_url": "/api/create_record", // 新增提交地址
|
||||||
|
"update_data_url": "/api/update_record", // 更新提交地址
|
||||||
|
"delete_data_url": "/api/delete_record" // 删除提交地址
|
||||||
|
},
|
||||||
|
|
||||||
|
// 行记录选项(传递给 build_record_view)
|
||||||
|
"row_options": {
|
||||||
|
"fields": [
|
||||||
|
{ "name": "title", "label": "标题", "uitype": "text" },
|
||||||
|
{ "name": "author", "label": "作者", "uitype": "text" },
|
||||||
|
{ "name": "pub_date", "label": "发布时间", "uitype": "date" }
|
||||||
|
],
|
||||||
|
"editexclouded": ["pub_date"] // 编辑时不显示的字段
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subwidgets": [], // DataViewer 自动管理子控件(通过 dataHandle 渲染),一般不手动添加
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "dataviewer_main",
|
||||||
|
"event": "row_check_changed",
|
||||||
|
"target": "logger_panel",
|
||||||
|
"method": "setValue",
|
||||||
|
"dataparams": {
|
||||||
|
"message": "Selected row changed: {{value}}"
|
||||||
|
},
|
||||||
|
"datamethod": "getValue", // 从事件中获取数据
|
||||||
|
"datawidget": "dataviewer_main"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "dataviewer_main",
|
||||||
|
"event": "add",
|
||||||
|
"target": "global_event_bus",
|
||||||
|
"dispatch_event": "open_statistics_panel",
|
||||||
|
"params": {
|
||||||
|
"action": "add",
|
||||||
|
"from": "DataViewer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "dataviewer_main",
|
||||||
|
"event": "update",
|
||||||
|
"target": "Popup",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Message",
|
||||||
|
"options": {
|
||||||
|
"title": "Success",
|
||||||
|
"message": "Record updated successfully!",
|
||||||
|
"level": "info"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ 注释说明:
|
||||||
|
|
||||||
|
- `"data_url"` 和 `"data_params"` 配合使用,由 `PageDataLoader` 自动发起请求。
|
||||||
|
- `"editable"` 开启后会在顶部生成包含增删改克隆图标的工具栏。
|
||||||
|
- `build_record_view()` 必须在子类中重写才能正确显示内容;否则默认显示一个空白方块。
|
||||||
|
- 工具栏按钮点击后会派发对应名称的事件(如 `add`, `update`),可用于联动其他模块。
|
||||||
|
- 使用 `binds` 可将用户操作与日志、提示、跳转等行为连接起来。
|
||||||
|
- 支持垂直滚动加载更多数据(上拉刷新 / 下拉加载)。
|
||||||
|
|
||||||
|
> 💡 提示:若要完全自定义界面,请继承 `DataViewer` 并重写 `build_record_view(record)` 方法返回你想要的控件结构。
|
||||||
184
docs/ai/docxviewer.md
Normal file
184
docs/ai/docxviewer.md
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# DOCXviewer
|
||||||
|
|
||||||
|
用于在前端界面中嵌入并渲染 `.docx`(Word 文档)文件的容器控件,继承自 `VBox`。通过 `mammoth.js` 将二进制 Word 文档转换为 HTML 并显示在页面中。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`set_url(url)`**
|
||||||
|
异步方法,接收一个文档 URL,使用 `HttpArrayBuffer` 获取二进制数据,并通过 `mammoth.convertToHtml` 转换为 HTML 后插入到控件的 DOM 中。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`on_parent`**
|
||||||
|
当控件被挂载到父级组件时触发,自动调用 `set_url(this.url)` 开始加载文档内容。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "docx_viewer_1",
|
||||||
|
"widgettype": "DOCXviewer",
|
||||||
|
"options": {
|
||||||
|
"url": "/documents/report.docx" // 要加载的 .docx 文件路径
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "btn_refresh_docx",
|
||||||
|
"event": "click",
|
||||||
|
"target": "docx_viewer_1",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "method",
|
||||||
|
"method": "set_url",
|
||||||
|
"params": {
|
||||||
|
"url": "/documents/report_updated.docx"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rtdata": {},
|
||||||
|
"conform": {
|
||||||
|
"title": "刷新确认",
|
||||||
|
"message": "确定要重新加载文档吗?",
|
||||||
|
"confirm_text": "确定",
|
||||||
|
"cancel_text": "取消"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注释:
|
||||||
|
> - `widgettype: DOCXviewer` 表示这是一个基于 Mammoth.js 渲染 Word 文档的控件。
|
||||||
|
> - `options.url` 指定远程 `.docx` 文件地址。
|
||||||
|
> - 使用 `binds` 可以绑定按钮点击事件来动态更新文档源。
|
||||||
|
> - 需提前引入 [mammoth.js](https://github.com/mwilliamson/mammoth.js) 库支持。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# EXCELviewer
|
||||||
|
|
||||||
|
用于在 Web 界面中展示 `.xlsx` 或 `.xls` Excel 文件内容的容器控件,继承自 `VBox`。支持多工作表切换查看,依赖 `SheetJS (xlsx)` 库解析 Excel 数据并渲染为 HTML 表格。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`set_url(url)`**
|
||||||
|
异步方法,根据传入的 Excel 文件 URL 加载二进制数据,使用 `XLSX.read()` 解析工作簿,并生成页签栏供用户切换不同 sheet。
|
||||||
|
|
||||||
|
- **`show_sheet_by_name(sheetname, tw)`**
|
||||||
|
切换显示指定名称的工作表,高亮当前选中标签,并将对应表格内容渲染至滚动面板中。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`on_parent`**
|
||||||
|
控件挂载后触发,自动调用 `set_url(this.url)` 初始化数据加载。
|
||||||
|
|
||||||
|
- **`click` on tab text widget**
|
||||||
|
点击某个工作表标签时,切换显示该工作表内容。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "excel_viewer_1",
|
||||||
|
"widgettype": "EXCELviewer",
|
||||||
|
"options": {
|
||||||
|
"url": "/data/sales_report.xlsx", // Excel 文件地址
|
||||||
|
"height": "600px"
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_load_another_excel",
|
||||||
|
"event": "click",
|
||||||
|
"target": "excel_viewer_1",
|
||||||
|
"method": "set_url",
|
||||||
|
"params": {
|
||||||
|
"url": "/data/inventory.xlsx"
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "加载新文件",
|
||||||
|
"message": "是否加载新的库存表格?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注释:
|
||||||
|
> - `EXCELviewer` 自动创建顶部可滚动的 sheet 标签栏和下方内容区。
|
||||||
|
> - 每个标签是一个 `Text` 控件,带有 `'clickable'` 和 `'selected'` CSS 类控制样式。
|
||||||
|
> - 内容使用 `XLSX.utils.sheet_to_html` 直接生成表格 HTML 插入 `VScrollPanel` 实现滚动。
|
||||||
|
> - 必须确保全局已加载 `xlsx.full.min.js`(如 SheetJS)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# PDFviewer
|
||||||
|
|
||||||
|
用于在前端展示 `.pdf` 文件的容器控件,继承自 `VBox`。利用 `pdfjsLib`(Mozilla PDF.js)解析 PDF 二进制流,并逐页渲染为 `<canvas>` 元素进行显示。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`set_url(url)`**
|
||||||
|
异步方法,从指定 URL 获取 PDF 二进制数据,初始化 `pdfjsLib.getDocument` 并遍历所有页面进行渲染。
|
||||||
|
|
||||||
|
- **`add_page_content(page)`**
|
||||||
|
接收一个 PDF 页面对象,创建 canvas 元素并调用 `page.render()` 绘制可视内容,添加到控件中。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`on_parent`**
|
||||||
|
控件挂载完成后触发,启动 PDF 加载流程。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "pdf_viewer_1",
|
||||||
|
"widgettype": "PDFviewer",
|
||||||
|
"options": {
|
||||||
|
"url": "/docs/manual.pdf", // PDF 文件路径
|
||||||
|
"width": "100%",
|
||||||
|
"height": "800px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "btn_print_pdf",
|
||||||
|
"event": "click",
|
||||||
|
"target": "Popup",
|
||||||
|
"script": "window.open(target.options.url, '_blank', 'print=yes');",
|
||||||
|
"params": {
|
||||||
|
"target": "pdf_viewer_1"
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"msg": "正在打开打印窗口..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_reload_pdf",
|
||||||
|
"event": "click",
|
||||||
|
"target": "pdf_viewer_1",
|
||||||
|
"method": "set_url",
|
||||||
|
"params": {
|
||||||
|
"url": "{{last_pdf_url}}" // 动态参数,来自运行时数据或变量
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注释:
|
||||||
|
> - `PDFviewer` 使用 `pdfjsLib` 的标准 API 加载和渲染 PDF。
|
||||||
|
> - 每页生成一个 `<canvas>` 并插入控件内部,页间可用 `Splitter` 分隔(代码中逻辑未完全闭合,需注意循环变量作用域)。
|
||||||
|
> - 需引入 PDF.js 并设置 `pdfjsLib.GlobalWorkerOptions.workerSrc`。
|
||||||
|
> - 示例中使用 `script` 动作实现“打印”功能,弹出新窗口预览 PDF。
|
||||||
|
> - `{{last_pdf_url}}` 表示支持模板变量注入,可用于动态刷新最近访问的文档。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> ✅ 所有三个控件均为**容器控件**,均继承自 `VBox`,可通过 `add_widget` 动态添加子控件。
|
||||||
|
> ⚠️ 使用前请确保相关第三方库已正确加载:
|
||||||
|
> - DOCXviewer → `mammoth`
|
||||||
|
> - EXCELviewer → `xlsx`
|
||||||
|
> - PDFviewer → `pdfjsLib`
|
||||||
219
docs/ai/dynamicaccordion.md
Normal file
219
docs/ai/dynamicaccordion.md
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
# DynamicAccordion
|
||||||
|
|
||||||
|
动态手风琴控件(DynamicAccordion)是一个容器控件,用于以分页、可折叠的方式展示大量数据记录。它继承自 `bricks.VScrollPanel`,支持懒加载、无限滚动、编辑操作和内容动态渲染,适用于需要高效展示结构化数据的场景(如后台管理列表、日志查看器等)。该控件结合了数据加载、视图模板、工具栏配置与交互逻辑,是 bricks 框架中功能较完整的复合型容器控件。
|
||||||
|
|
||||||
|
类型:容器控件,继承自 `VScrollPanel`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`render(params)`**
|
||||||
|
根据参数重新加载并渲染数据。若传入 `params`,会作为请求参数发送至后端接口。此方法触发数据加载与界面更新。
|
||||||
|
|
||||||
|
- **`build_item(record)`**
|
||||||
|
构建单个手风琴项(AccordionItem),包含标题信息区域和隐藏的内容区域。如果 record 存在,则绑定点击事件以展开内容。
|
||||||
|
|
||||||
|
- **`toggle_content(info, content, record, event)`**
|
||||||
|
切换指定项的内容区域显示/隐藏状态。首次展开时按需加载并渲染 `content_view` 定义的子控件。
|
||||||
|
|
||||||
|
- **`line_clicked(info, content, record, event)`**
|
||||||
|
行点击回调函数,处理选中高亮及内容切换逻辑。
|
||||||
|
|
||||||
|
- **`load_previous_page()` / `load_next_page()`**
|
||||||
|
分别加载前一页或下一页数据,实现“无限滚动”效果,基于 `min_threshold` 和 `max_threshold` 事件触发。
|
||||||
|
|
||||||
|
- **`add_record(info)`**
|
||||||
|
添加新记录,通常通过表单输入完成,并提交到服务器。
|
||||||
|
|
||||||
|
- **`update_record(info, record)`**
|
||||||
|
更新当前记录,弹出可编辑表单。
|
||||||
|
|
||||||
|
- **`delete_record(info, record)`**
|
||||||
|
删除指定记录,弹出确认对话框防止误操作。
|
||||||
|
|
||||||
|
- **`build_record_toolbar(info, record)`**
|
||||||
|
构建每行右侧的操作工具栏(如增删改图标按钮),支持自定义扩展事件。
|
||||||
|
|
||||||
|
- **`fire_event(event_name, data)`**
|
||||||
|
向外派发自定义事件,供外部监听使用(例如用于联动其他组件)。
|
||||||
|
|
||||||
|
- **`select_line(info)`**
|
||||||
|
设置某行为选中状态,并取消之前选中的行样式。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 |
|
||||||
|
|--------------------|--------|
|
||||||
|
| `row_selected` | 当用户点击某一行时触发,携带被点击行的信息组件 `info` 作为参数。可用于与其他控件联动。 |
|
||||||
|
| `conformed` | 在删除确认弹窗中点击“确定”后触发,执行实际删除动作。 |
|
||||||
|
| `submited` | 表单提交成功后触发,常用于刷新视图或关闭弹窗。 |
|
||||||
|
| `cancel` | 编辑/新增表单取消时触发,关闭表单区域。 |
|
||||||
|
| `min_threshold` | 垂直滚动条接近顶部时触发,由 `container` 内部发出,用于加载上一页数据。 |
|
||||||
|
| `max_threshold` | 垂直滚动条接近底部时触发,用于加载下一页数据。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "dynamic_accordion_example",
|
||||||
|
"widgettype": "DynamicAccordion",
|
||||||
|
"options": {
|
||||||
|
// 数据源 URL,返回符合 PageDataLoader 格式的 JSON
|
||||||
|
"data_url": "/api/records/list",
|
||||||
|
"data_params": {
|
||||||
|
"category": "news"
|
||||||
|
},
|
||||||
|
"data_method": "GET",
|
||||||
|
|
||||||
|
// 分页设置
|
||||||
|
"page_rows": 10,
|
||||||
|
"cache_limit": 5,
|
||||||
|
|
||||||
|
// 每行高度倍数(相对于标准行高)
|
||||||
|
"row_cheight": 1.5,
|
||||||
|
|
||||||
|
// 是否启用编辑功能
|
||||||
|
"editable": {
|
||||||
|
"form_cheight": 8,
|
||||||
|
"add_icon": "/static/icons/add.svg",
|
||||||
|
"update_icon": "/static/icons/edit.svg",
|
||||||
|
"delete_icon": "/static/icons/trash.svg",
|
||||||
|
"new_data_url": "/api/records/create",
|
||||||
|
"update_data_url": "/api/records/update",
|
||||||
|
"delete_data_url": "/api/records/delete"
|
||||||
|
},
|
||||||
|
|
||||||
|
// 头部标题与描述(可选)
|
||||||
|
"title": "新闻列表",
|
||||||
|
"description": "点击查看详细内容",
|
||||||
|
|
||||||
|
// 工具栏定义(可选)
|
||||||
|
"toolbar": {
|
||||||
|
"tools": [
|
||||||
|
{ "name": "refresh", "icon": "/static/icons/refresh.svg", "tip": "刷新列表" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 字段定义,用于构建表单或标题展示
|
||||||
|
"fields": [
|
||||||
|
{ "name": "title", "label": "标题", "uitype": "text" },
|
||||||
|
{ "name": "author", "label": "作者", "uitype": "text" },
|
||||||
|
{ "name": "pub_date", "label": "发布时间", "uitype": "date" }
|
||||||
|
],
|
||||||
|
|
||||||
|
// 每行记录的视图模板(用于 header 显示)
|
||||||
|
"record_view": {
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": { "padding": 10 },
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "{title}",
|
||||||
|
"i18n": false,
|
||||||
|
"halign": "left",
|
||||||
|
"style": { "font-weight": "bold", "margin-right": "10px" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "by {author}",
|
||||||
|
"i18n": false,
|
||||||
|
"halign": "left",
|
||||||
|
"style": { "color": "#666", "font-size": "0.9em" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 展开后显示的详细内容视图
|
||||||
|
"content_view": {
|
||||||
|
"widgettype": "Form",
|
||||||
|
"options": {
|
||||||
|
"submit_url": "/api/records/update",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "title", "label": "标题", "uitype": "text" },
|
||||||
|
{ "name": "content", "label": "正文", "uitype": "textarea", "cheight": 5 },
|
||||||
|
{ "name": "status", "label": "状态", "uitype": "select", "options": ["草稿", "已发布"] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 自定义每行的操作按钮(除编辑外)
|
||||||
|
"record_toolbar": {
|
||||||
|
"cwidth": 2.5,
|
||||||
|
"tools": [
|
||||||
|
{ "name": "share", "icon": "/static/icons/share.svg", "tip": "分享此条目" },
|
||||||
|
{ "name": "export", "icon": "/static/icons/export.svg", "tip": "导出为 PDF" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 控制何时才渲染 content_view(条件依赖字段)
|
||||||
|
"content_rely_on": "has_detail",
|
||||||
|
"content_rely_value": true
|
||||||
|
},
|
||||||
|
|
||||||
|
// 绑定事件
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "dynamic_accordion_example",
|
||||||
|
"event": "row_selected",
|
||||||
|
"target": "another_panel",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "Selected: {user_data.title}",
|
||||||
|
"i18n": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mode": "replace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "dynamic_accordion_example",
|
||||||
|
"event": "refresh",
|
||||||
|
"target": "dynamic_accordion_example",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/records/list",
|
||||||
|
"method": "GET",
|
||||||
|
"params": { "force_refresh": true }
|
||||||
|
},
|
||||||
|
"mode": "replace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "dynamic_accordion_example",
|
||||||
|
"event": "share",
|
||||||
|
"target": "Popup",
|
||||||
|
"dispatch_event": "show_share_dialog",
|
||||||
|
"params": { "record": "{user_data}" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
>
|
||||||
|
> - `data_url` 提供分页数据接口,返回格式应为 `{ rows: [...], page: 1, total: 100 }`
|
||||||
|
> - `record_view` 定义每一行如何显示简略信息。
|
||||||
|
> - `content_view` 定义展开后的详细内容,仅在点击时动态加载。
|
||||||
|
> - `editable` 开启内置增删改功能,自动添加操作图标。
|
||||||
|
> - `binds` 中监听 `row_selected` 实现跨组件通信;`refresh` 按钮重新加载数据。
|
||||||
|
> - 使用 `{field_name}` 占位符可在文本或参数中引用运行时数据(来自 record)。
|
||||||
|
> - `content_rely_on` 可控制是否显示展开内容,提高性能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
📌 **总结:**
|
||||||
|
`DynamicAccordion` 是一个高度集成的数据展示控件,适合构建复杂的数据浏览界面。其核心优势在于:
|
||||||
|
- 支持大数据量下的分页懒加载;
|
||||||
|
- 提供灵活的视图定制能力;
|
||||||
|
- 内建 CRUD 支持与事件系统;
|
||||||
|
- 易于通过 JSON 配置实现复杂交互逻辑。
|
||||||
131
docs/ai/dynamiccolumn.md
Normal file
131
docs/ai/dynamiccolumn.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# DynamicColumn
|
||||||
|
|
||||||
|
`DynamicColumn` 是一个**容器控件**,继承自 `bricks.Layout`。它用于实现响应式网格布局,能够根据屏幕宽度动态调整列数和列宽,特别适用于移动端与桌面端自适应的卡片式布局场景。
|
||||||
|
|
||||||
|
该控件通过 CSS Grid 实现布局,并在窗口尺寸变化或父容器更新时自动重新计算列宽与间隙,确保内容均匀分布且美观。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`set_column_width()`**
|
||||||
|
核心方法,负责根据当前设备类型(移动端/桌面端)、字符单位大小(`charsize`)以及配置参数动态设置 `gridTemplateColumns` 和 `gap` 样式属性。
|
||||||
|
|
||||||
|
- 在移动端竖屏下使用固定的列数(由 `mobile_cols` 控制)
|
||||||
|
- 在桌面端根据 `col_cwidth`(以字符为单位的列宽)或直接指定的 `col_width`(像素值)来计算每列最小宽度
|
||||||
|
- 使用 `minmax(cw + "px", 1fr)` 配合 `repeat(auto-fill, ...)` 实现自动换行和等分布局
|
||||||
|
|
||||||
|
- **构造函数 `constructor(opts)`**
|
||||||
|
初始化控件选项并绑定事件:
|
||||||
|
- 自动补全默认值:`col_cwidth`, `col_cgap`, `mobile_cols`
|
||||||
|
- 设置 `display: grid`
|
||||||
|
- 绑定生命周期和窗口 resize 事件以触发布局重算
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`on_parent`**
|
||||||
|
当控件被添加到父容器后触发,用于首次设置列宽。
|
||||||
|
|
||||||
|
- **`resize`**
|
||||||
|
浏览器窗口大小改变时触发,动态调整网格列数和间距。
|
||||||
|
|
||||||
|
- **`charsize` (全局事件)**
|
||||||
|
字符尺寸变化时触发(通常因主题切换或缩放引起),重新计算基于字符单位的列宽。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "dynamicGrid",
|
||||||
|
"widgettype": "DynamicColumn",
|
||||||
|
"options": {
|
||||||
|
"col_cwidth": 20, // 每列最小宽度 = 20ch(字符单位),推荐方式
|
||||||
|
"col_cgap": 0.5, // 列间间隙 = 0.5ch
|
||||||
|
"mobile_cols": 1, // 移动端显示为单列
|
||||||
|
"style": {
|
||||||
|
"padding": "10px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "card1",
|
||||||
|
"widgettype": "Div",
|
||||||
|
"options": {
|
||||||
|
"text": "卡片 1",
|
||||||
|
"style": {
|
||||||
|
"background": "#f0f0f0",
|
||||||
|
"border": "1px solid #ccc",
|
||||||
|
"padding": "20px",
|
||||||
|
"textAlign": "center",
|
||||||
|
"borderRadius": "8px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "card2",
|
||||||
|
"widgettype": "Div",
|
||||||
|
"options": {
|
||||||
|
"text": "卡片 2",
|
||||||
|
"style": {
|
||||||
|
"background": "#e0e0e0",
|
||||||
|
"border": "1px solid #bbb",
|
||||||
|
"padding": "20px",
|
||||||
|
"textAlign": "center",
|
||||||
|
"borderRadius": "8px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "card3",
|
||||||
|
"widgettype": "Div",
|
||||||
|
"options": {
|
||||||
|
"text": "卡片 3",
|
||||||
|
"style": {
|
||||||
|
"background": "#d0d0d0",
|
||||||
|
"border": "1px solid #aaa",
|
||||||
|
"padding": "20px",
|
||||||
|
"textAlign": "center",
|
||||||
|
"borderRadius": "8px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "dynamicGrid",
|
||||||
|
"event": "resize",
|
||||||
|
"target": "dynamicGrid",
|
||||||
|
"method": "set_column_width",
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "dynamicGrid",
|
||||||
|
"event": "on_parent",
|
||||||
|
"target": "dynamicGrid",
|
||||||
|
"method": "set_column_width",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `col_cwidth`: 推荐使用字符单位(ch),可保证文字排版对齐一致性
|
||||||
|
> - `col_cgap`: 间隙也基于字符单位,随字体缩放而变化,提升可访问性
|
||||||
|
> - `mobile_cols`: 竖屏手机强制显示为单列,提升阅读体验
|
||||||
|
> - 所有子控件将自动填入网格中,浏览器自行处理换行与对齐
|
||||||
|
> - `binds` 中显式调用 `set_column_width` 确保初始和变更时正确渲染
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
💡 **使用建议:**
|
||||||
|
|
||||||
|
- 若希望固定列数,请结合 `minmax()` 和 `auto-fit` 使用其他布局策略
|
||||||
|
- 可配合 `urlwidget` 动态加载子项,实现无限滚动卡片墙
|
||||||
|
- 支持国际化文本变动引起的宽度变化,只要触发 `charsize` 更新即可自动适配
|
||||||
320
docs/ai/factory.md
Normal file
320
docs/ai/factory.md
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
# Button
|
||||||
|
|
||||||
|
按钮控件,用于触发用户交互操作。类型:普通控件,继承自 `JsWidget`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `setValue(text: string)`
|
||||||
|
设置按钮显示的文本内容。
|
||||||
|
|
||||||
|
- `getValue(): string`
|
||||||
|
获取按钮当前显示的文本。
|
||||||
|
|
||||||
|
- `enable()`
|
||||||
|
启用按钮,允许用户点击。
|
||||||
|
|
||||||
|
- `disable()`
|
||||||
|
禁用按钮,禁止用户点击并呈现灰化状态。
|
||||||
|
|
||||||
|
- `show()`
|
||||||
|
显示按钮。
|
||||||
|
|
||||||
|
- `hide()`
|
||||||
|
隐藏按钮。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `click`
|
||||||
|
用户点击按钮时触发。
|
||||||
|
|
||||||
|
- `focus`
|
||||||
|
按钮获得焦点时触发。
|
||||||
|
|
||||||
|
- `blur`
|
||||||
|
按钮失去焦点时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "btn_submit", // 控件唯一ID
|
||||||
|
"widgettype": "Button", // 控件类型:Button
|
||||||
|
"options": {
|
||||||
|
"value": "提交", // 初始按钮文本
|
||||||
|
"disabled": false, // 是否禁用,默认为false
|
||||||
|
"style": "primary", // 可选样式:primary, secondary, danger等
|
||||||
|
"tooltip": "点击提交表单" // 鼠标悬停提示
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method", // 动作类型:调用方法
|
||||||
|
"wid": "btn_submit", // 触发组件ID
|
||||||
|
"event": "click", // 监听点击事件
|
||||||
|
"target": "form_data", // 目标组件ID
|
||||||
|
"method": "submit", // 调用目标的方法名
|
||||||
|
"params": {} // 方法参数
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script", // 执行脚本动作
|
||||||
|
"wid": "btn_submit",
|
||||||
|
"event": "click",
|
||||||
|
"target": "btn_submit",
|
||||||
|
"script": "console.log('按钮被点击:', data); return true;",
|
||||||
|
"params": {
|
||||||
|
"data": "提交日志记录"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Panel
|
||||||
|
|
||||||
|
面板控件,用于布局容器,可包含多个子控件。类型:容器控件,继承自 `JsWidget`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `addSubwidget(widgetJson)`
|
||||||
|
动态添加一个子控件(JSON 描述)到面板中。
|
||||||
|
|
||||||
|
- `removeSubwidget(widgetId: string)`
|
||||||
|
移除指定 ID 的子控件。
|
||||||
|
|
||||||
|
- `clear()`
|
||||||
|
清空所有子控件。
|
||||||
|
|
||||||
|
- `show()`
|
||||||
|
显示整个面板。
|
||||||
|
|
||||||
|
- `hide()`
|
||||||
|
隐藏面板。
|
||||||
|
|
||||||
|
- `setTitle(title: string)`
|
||||||
|
设置面板标题(如果支持标题栏)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `init`
|
||||||
|
面板初始化完成后触发。
|
||||||
|
|
||||||
|
- `rendered`
|
||||||
|
所有子控件渲染完成时触发。
|
||||||
|
|
||||||
|
- `childadded`
|
||||||
|
添加子控件后触发,携带新控件信息。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "panel_user_info", // 容器ID
|
||||||
|
"widgettype": "Panel", // 控件类型:Panel
|
||||||
|
"options": {
|
||||||
|
"title": "用户信息", // 面板标题
|
||||||
|
"collapsible": true, // 是否可折叠
|
||||||
|
"collapsed": false, // 初始是否折叠
|
||||||
|
"border": true, // 是否显示边框
|
||||||
|
"layout": "vertical" // 布局方式:vertical / horizontal
|
||||||
|
},
|
||||||
|
"subwidgets": [ // 子控件数组
|
||||||
|
{
|
||||||
|
"id": "label_name",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"value": "姓名:张三"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "label_age",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"value": "年龄:28"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_edit",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"value": "编辑"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "btn_edit",
|
||||||
|
"event": "click",
|
||||||
|
"target": "panel_user_info",
|
||||||
|
"dispatch_event": "editmode_enter",
|
||||||
|
"params": {
|
||||||
|
"user_id": 1001
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks", // 在本地创建新的Bricks组件
|
||||||
|
"wid": "panel_user_info",
|
||||||
|
"event": "init",
|
||||||
|
"target": "Popup", // 特殊目标:弹窗管理器
|
||||||
|
"mode": "append",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Toast",
|
||||||
|
"options": {
|
||||||
|
"text": "用户面板已加载",
|
||||||
|
"duration": 2000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UrlWidget
|
||||||
|
|
||||||
|
远程组件加载控件,用于动态从服务器加载界面模块。类型:普通控件或容器控件(取决于加载内容),继承自 `JsWidget`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `reload(params?: Object)`
|
||||||
|
使用新的参数重新请求远程URL,刷新组件。
|
||||||
|
|
||||||
|
- `getLoadedWidget(): JsWidget | null`
|
||||||
|
获取已加载的实际控件实例,若未加载完成则返回 null。
|
||||||
|
|
||||||
|
- `isLoading(): boolean`
|
||||||
|
判断是否正在加载远程资源。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `loadstart`
|
||||||
|
开始加载远程组件时触发。
|
||||||
|
|
||||||
|
- `loadsuccess`
|
||||||
|
成功加载并渲染完成远程组件后触发。
|
||||||
|
|
||||||
|
- `loaderror`
|
||||||
|
加载失败时触发,携带错误信息。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "dynamic_content",
|
||||||
|
"widgettype": "UrlWidget", // 特殊控件类型,用于远程加载
|
||||||
|
"options": {
|
||||||
|
"url": "/api/widgets/profile.ui", // 远程 .ui 文件地址
|
||||||
|
"method": "GET", // HTTP 方法
|
||||||
|
"params": { // 请求参数
|
||||||
|
"userid": "{% userid %}", // 支持模板变量注入
|
||||||
|
"lang": "zh-CN"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "dynamic_content",
|
||||||
|
"event": "click", // 示例:通过点击重新加载
|
||||||
|
"target": "dynamic_content",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/widgets/profile.ui",
|
||||||
|
"method": "POST",
|
||||||
|
"params": {
|
||||||
|
"userid": "12345",
|
||||||
|
"refresh": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "registerfunction",
|
||||||
|
"wid": "dynamic_content",
|
||||||
|
"event": "loadsuccess",
|
||||||
|
"target": "_t_", // 全局上下文
|
||||||
|
"rfname": "trackPageView", // 调用注册过的全局函数
|
||||||
|
"params": {
|
||||||
|
"page": "UserProfile"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "conform", // 错误处理示例
|
||||||
|
"wid": "dynamic_content",
|
||||||
|
"event": "loaderror",
|
||||||
|
"target": "Popup",
|
||||||
|
"rtdata": {
|
||||||
|
"title": "加载失败",
|
||||||
|
"content": "无法获取用户资料,请稍后再试。"
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "网络错误",
|
||||||
|
"content": "加载用户数据失败,是否重试?",
|
||||||
|
"buttons": ["Cancel", "Retry"],
|
||||||
|
"onConfirm": {
|
||||||
|
"actiontype": "method",
|
||||||
|
"target": "dynamic_content",
|
||||||
|
"method": "reload"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注:`UrlWidget` 是实现模块化开发的核心控件,支持按需加载 `.ui` 文件,提升首屏性能和代码分割能力。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Label
|
||||||
|
|
||||||
|
标签控件,用于展示静态文本信息。类型:普通控件,继承自 `JsWidget`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `setValue(text: string)`
|
||||||
|
设置标签显示的文本内容。
|
||||||
|
|
||||||
|
- `getValue(): string`
|
||||||
|
获取当前显示的文本。
|
||||||
|
|
||||||
|
- `setHtml(html: string)`
|
||||||
|
设置 HTML 内容(注意 XSS 防护)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `click`
|
||||||
|
用户点击标签时触发(可用于可交互标签)。
|
||||||
|
|
||||||
|
- `dblclick`
|
||||||
|
双击事件。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "lbl_instructions",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"value": "请填写以下必填字段 *", // 显示文本
|
||||||
|
"cssClass": "instruction-text", // 自定义CSS类
|
||||||
|
"align": "left", // 对齐方式:left/center/right
|
||||||
|
"html": false // 是否解析HTML
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "lbl_instructions",
|
||||||
|
"event": "click",
|
||||||
|
"target": "help_dialog",
|
||||||
|
"dispatch_event": "open"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **说明**:以上控件文档遵循 Bricks.js 框架的 JSON 结构规范,适用于 `.ui` 文件编写与可视化工具生成。每个控件均以 `id` 唯一标识,并通过 `binds` 实现事件驱动逻辑,支持动态加载、脚本执行、方法调用等多种交互模式。
|
||||||
81
docs/ai/floaticonbar.md
Normal file
81
docs/ai/floaticonbar.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# IconBar
|
||||||
|
|
||||||
|
用于创建一个图标工具栏,支持多个可点击的图标按钮,常用于顶部或侧边导航工具条。属于**容器控件**,继承自 `bricks.HBox`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `build_item(opts)`
|
||||||
|
根据传入的图标配置项创建单个图标控件(`Svg` 或 `BlankIcon`),并绑定点击事件。
|
||||||
|
|
||||||
|
- `regen_event(desc, event)`
|
||||||
|
处理图标点击后的逻辑:触发对应图标的命名事件和统一的 `'command'` 事件,并管理选中状态样式。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `dispatch(desc.name, desc)`
|
||||||
|
当某个图标被点击时,会派发以该图标 `name` 命名的自定义事件,携带图标描述对象作为参数。
|
||||||
|
|
||||||
|
- `dispatch('command', desc)`
|
||||||
|
所有图标点击都会统一触发 `'command'` 事件,可用于集中处理工具栏命令。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "icon_toolbar",
|
||||||
|
"widgettype": "IconBar",
|
||||||
|
"options": {
|
||||||
|
"margin": "10px", // 图标之间的左右外边距
|
||||||
|
"rate": 1, // 缩放比率,影响图标大小
|
||||||
|
"cheight": 2, // 图标高度单位(基于字符高度)
|
||||||
|
"tools": [ // 工具图标列表
|
||||||
|
{
|
||||||
|
"name": "save", // 图标唯一标识名称
|
||||||
|
"icon": "/static/icons/save.svg", // SVG 图标路径
|
||||||
|
"tip": "保存文件", // 提示文本(可选)
|
||||||
|
"rate": 1 // 单独设置此图标的缩放比例
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "print",
|
||||||
|
"icon": "/static/icons/print.svg",
|
||||||
|
"tip": "打印当前页面"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blankicon" // 特殊类型:空白占位图标
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "icon_toolbar",
|
||||||
|
"event": "save", // 监听名为 'save' 的事件(由点击 save 图标触发)
|
||||||
|
"target": "main_app",
|
||||||
|
"dispatch_event": "onSave",
|
||||||
|
"params": {
|
||||||
|
"from": "toolbar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "icon_toolbar",
|
||||||
|
"event": "command", // 监听所有命令
|
||||||
|
"target": "Popup",
|
||||||
|
"script": "console.log('执行命令:', params.name); if(params.tip) showTip(params.tip);",
|
||||||
|
"params": {
|
||||||
|
"name": "{data.name}", // 动态获取事件数据中的 name 字段
|
||||||
|
"tip": "{data.tip}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subwidgets": [] // IconBar 自身是容器,但通常不手动添加 subwidgets,由 tools 自动生成
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `tools` 数组中每个对象代表一个图标按钮;
|
||||||
|
> - `name` 是事件分发的关键标识;
|
||||||
|
> - `icon` 必须指向有效的 SVG 资源 URL;
|
||||||
|
> - 使用 `blankicon` 可插入空格占位符;
|
||||||
|
> - 通过 `binds` 可监听具体图标事件或统一的 `command` 事件进行响应;
|
||||||
|
> - `FloatIconBar` 和 `IconTextBar` 分别扩展了浮动显示与图文混合功能。
|
||||||
159
docs/ai/form.md
Normal file
159
docs/ai/form.md
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
# InlineForm
|
||||||
|
|
||||||
|
`InlineForm` 是一个轻量级的表单控件,用于在界面中嵌入行内表单输入区域。它继承自 `FormBase`,属于**普通控件**(虽然其内部结构可包含多个子控件,但本身不作为容器管理布局),主要用于快速构建无需独立弹窗或页面的表单操作场景。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|-------|------|
|
||||||
|
| `build_fields(form, parent, fields)` | 通过 `FieldGroup` 构建字段集合,根据字段类型生成对应的输入控件并添加到父容器中。 |
|
||||||
|
| `save_origin_data()` | 保存当前所有字段的初始值,用于后续比对是否发生更改(配合 `submit_changed` 使用)。 |
|
||||||
|
| `get_formdata()` | 获取表单数据,支持 `FormData` 格式输出,并可选择仅提交变更字段。若验证失败则返回 `null`。 |
|
||||||
|
| `validation()` | 验证表单必填项,触发提交事件并可向服务器发送请求(如果配置了 `submit_url`)。过程中会显示“正在提交”动画。 |
|
||||||
|
| `reset_data()` | 将所有输入控件重置为其初始值。 |
|
||||||
|
| `cancel()` | 派发 `cancel` 自定义事件,通常用于关闭表单或取消操作流程。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 参数说明 |
|
||||||
|
|--------|---------|----------|
|
||||||
|
| `submit` | 用户点击“提交”按钮后,通过验证时触发 | 包含表单数据的对象(如 `{ name: "value" }`) |
|
||||||
|
| `submited` | 提交完成后,从服务器收到响应时触发 | `Response` 对象(来自 `fetch` 的响应) |
|
||||||
|
| `cancel` | 点击“取消”按钮时触发 | 无参数 |
|
||||||
|
| `command` | 工具栏按钮点击时由 `IconTextBar` 派发,被 `command_handle` 处理 | `{ name: 'submit' \| 'reset' \| 'cancel' }` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "user_profile_inline",
|
||||||
|
"widgettype": "InlineForm",
|
||||||
|
"options": {
|
||||||
|
// 表单整体宽度和高度自适应
|
||||||
|
"width": "100%",
|
||||||
|
"height": "auto",
|
||||||
|
|
||||||
|
// 定义表单项列表
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"label": "用户名",
|
||||||
|
"uitype": "textinput",
|
||||||
|
"required": true,
|
||||||
|
"placeholder": "请输入用户名"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"label": "邮箱地址",
|
||||||
|
"uitype": "email",
|
||||||
|
"required": true,
|
||||||
|
"placeholder": "example@domain.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "age",
|
||||||
|
"label": "年龄",
|
||||||
|
"uitype": "number",
|
||||||
|
"min": 1,
|
||||||
|
"max": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gender",
|
||||||
|
"label": "性别",
|
||||||
|
"uitype": "select",
|
||||||
|
"options": [
|
||||||
|
{ "label": "男", "value": "male" },
|
||||||
|
{ "label": "女", "value": "female" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// 设置为 true 时只提交修改过的字段(默认 false)
|
||||||
|
"submit_changed": false,
|
||||||
|
|
||||||
|
// 提交目标 URL
|
||||||
|
"submit_url": "/api/update_profile",
|
||||||
|
|
||||||
|
// 使用 PUT 方法更新数据
|
||||||
|
"method": "PUT"
|
||||||
|
},
|
||||||
|
|
||||||
|
// 绑定事件处理逻辑
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "user_profile_inline",
|
||||||
|
"event": "submit",
|
||||||
|
"target": "Popup",
|
||||||
|
"mode": "append",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Running",
|
||||||
|
"message": "正在保存..."
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"form_id": "user_profile_inline"
|
||||||
|
},
|
||||||
|
"conform": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "user_profile_inline",
|
||||||
|
"event": "submited",
|
||||||
|
"target": "content_area",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/views/profile_summary.ui",
|
||||||
|
"params": {},
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"refresh": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "user_profile_inline",
|
||||||
|
"event": "cancel",
|
||||||
|
"target": "ModalDialog",
|
||||||
|
"dispatch_event": "close"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "user_profile_inline",
|
||||||
|
"event": "submit",
|
||||||
|
"target": "",
|
||||||
|
"script": "console.log('表单提交数据:', params.data);",
|
||||||
|
"params": {
|
||||||
|
"data": "{getDataFromWidget('user_profile_inline')}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
>
|
||||||
|
> - `InlineForm` 不创建新页面或弹窗,适合嵌入现有布局。
|
||||||
|
> - `fields` 中每个字段使用 `uitype` 定义输入类型,框架自动调用 `Input.factory()` 创建对应控件。
|
||||||
|
> - `binds` 实现了完整的交互闭环:
|
||||||
|
> - 提交前显示加载提示(`Running` 动画);
|
||||||
|
> - 提交成功后刷新内容区(通过 `urlwidget` 加载新视图);
|
||||||
|
> - 取消时通知模态框关闭;
|
||||||
|
> - 同时记录日志脚本用于调试。
|
||||||
|
> - 支持国际化字段(`i18n: true` 在底层 Text 控件中已启用)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
✅ **适用场景:**
|
||||||
|
- 内联编辑用户信息
|
||||||
|
- 快速填写短表单(如搜索、筛选条件)
|
||||||
|
- 在卡片或列表项中直接编辑数据
|
||||||
|
|
||||||
|
🔧 **注意事项:**
|
||||||
|
- 若涉及文件上传(`file`, `video`, `audio` 类型),需确保 `need_formdata = true`,框架将自动使用 `FormData` 提交。
|
||||||
|
- 所有字段必须有唯一 `name`,否则无法正确收集数据。
|
||||||
131
docs/ai/gobang.md
Normal file
131
docs/ai/gobang.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# GobangPoint
|
||||||
|
|
||||||
|
用于表示围棋棋盘上的一个交叉点,根据状态(空、黑子、白子)动态加载对应图片资源。继承自 `bricks.Image`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `calc_url()`
|
||||||
|
根据当前点的坐标 `(p_x, p_y)` 和状态 `p_status` 计算应显示的图片路径。规则如下:
|
||||||
|
- 坐标边缘情况:上下左右用 `'t'`, `'b'`, `'l'`, `'r'` 表示,中间为 `'c'`
|
||||||
|
- 状态映射:0 → `'empty'`,1 → `'black'`,2 → `'white'`
|
||||||
|
- 图片命名格式:`imgs/[vpos][hpos]_[status].png`,例如 `imgs/cl_black.png`
|
||||||
|
|
||||||
|
- `getValue()`
|
||||||
|
返回该点的状态对象,包含:
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
status: this.p_status,
|
||||||
|
x: this.p_x,
|
||||||
|
y: this.p_y
|
||||||
|
}
|
||||||
|
```
|
||||||
|
可用于获取棋子位置和颜色信息。
|
||||||
|
|
||||||
|
- `str()`
|
||||||
|
返回该点的字符串表示,格式为 `(status,x,y)`,主要用于调试输出。
|
||||||
|
|
||||||
|
- `set_current_position(flg)`
|
||||||
|
鼠标移入时设置 CSS 类 `curpos` 为 false(实际是通过 `!flg` 控制),可用于高亮当前悬停位置(需配合样式定义)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `mouseover`
|
||||||
|
触发时调用 `set_current_position(true)`,可用来实现悬停视觉反馈。
|
||||||
|
|
||||||
|
- `mouseout`
|
||||||
|
触发时调用 `set_current_position(false)`,取消悬停效果。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "point_3_4",
|
||||||
|
"widgettype": "GobangPoint",
|
||||||
|
"options": {
|
||||||
|
"p_status": 0, // 当前状态:0=空,1=黑,2=白
|
||||||
|
"p_x": 3, // 横向坐标,范围 1-15
|
||||||
|
"p_y": 4, // 纵向坐标,范围 1-15
|
||||||
|
"tip": "(3,4)" // 提示文本,鼠标悬停时显示
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "point_3_4",
|
||||||
|
"event": "click",
|
||||||
|
"target": "game_controller", // 假设存在游戏控制器组件
|
||||||
|
"method": "makeMove",
|
||||||
|
"params": {
|
||||||
|
"datawidget": "point_3_4",
|
||||||
|
"datamethod": "getValue" // 调用 getValue 获取坐标与状态
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明**:
|
||||||
|
> - 此控件通过 `p_status`, `p_x`, `p_y` 构造参数决定其外观。
|
||||||
|
> - 使用 `binds` 在点击时将自身数据传递给主控制器进行落子逻辑处理。
|
||||||
|
> - 图片资源路径由 `calc_url()` 自动生成,依赖于项目中 `/imgs/` 目录下的切图资源。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Gobang
|
||||||
|
|
||||||
|
代表一个完整的围棋对弈界面控件,管理15×15的棋盘点阵,并支持响应式布局调整。继承自 `bricks.VBox`,属于**容器控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `render_empty_area()`
|
||||||
|
创建15×15的 `GobangPoint` 网格并填充到内部的 `VBox` 中,初始状态均为“空”。使用嵌套循环生成行列结构,并保存引用至 `this.area[i][j]` 数组以便后续操作。
|
||||||
|
|
||||||
|
- `resize_area()`
|
||||||
|
根据父容器尺寸自动缩放每个棋盘点的大小。取 `filler` 容器宽高中较小值除以15作为单个格子尺寸,确保棋盘等比适应窗口变化。
|
||||||
|
|
||||||
|
- `inform_go(party)`
|
||||||
|
(目前为空实现)预留方法,用于通知轮到哪一方下棋(如 `'black'` 或 `'white'`),可用于AI触发或状态提示。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `element_resize`(来自 `Filler` 子控件)
|
||||||
|
当填充区域尺寸改变时触发,自动调用 `resize_area()` 方法重绘棋盘格子大小,实现自适应布局。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "gobang_game",
|
||||||
|
"widgettype": "Gobang",
|
||||||
|
"options": {},
|
||||||
|
"subwidgets": [], // 实际上在构造函数中动态创建,无需在 JSON 中显式列出
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "gobang_game",
|
||||||
|
"event": "load", // 假设框架支持 load 事件
|
||||||
|
"script": "console.log('围棋游戏已加载完成');"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "some_button",
|
||||||
|
"event": "click",
|
||||||
|
"target": "gobang_game",
|
||||||
|
"method": "inform_go",
|
||||||
|
"params": {
|
||||||
|
"party": "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明**:
|
||||||
|
> - `Gobang` 是一个复合容器控件,在初始化时通过代码动态构建子控件网格(`GobangPoint`),因此 `subwidgets` 在 JSON 中留空。
|
||||||
|
> - 使用 `Filler` 占位并监听其 `element_resize` 事件,实现响应式设计。
|
||||||
|
> - 可扩展绑定外部按钮来控制回合切换,未来可集成 AI 对手或网络对战功能。
|
||||||
|
> - 若需远程加载此游戏模块,可用 `urlwidget` 方式按需加载。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
📌 **总结建议**:
|
||||||
|
以上两个控件共同构成一个可交互、可扩展的围棋界面基础。`GobangPoint` 封装视觉与状态逻辑,`Gobang` 负责整体布局与协调。结合 bricks 的模块化能力(如 `urlwidget` 动态加载),非常适合开发复杂交互类 Web 应用。
|
||||||
58
docs/ai/html.md
Normal file
58
docs/ai/html.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Html
|
||||||
|
|
||||||
|
Html 是一个用于在页面中插入原始 HTML 内容的**普通控件**,继承自 `JsWidget`。它允许开发者通过配置 `html` 选项直接渲染任意 HTML 字符串,适用于展示富文本、静态内容或嵌入第三方 HTML 片段。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`setValue(html: string)`**
|
||||||
|
更新控件内的 HTML 内容,等同于重新设置 `innerHTML`。
|
||||||
|
|
||||||
|
- **`getValue(): string`**
|
||||||
|
返回当前控件容器内的 HTML 字符串内容。
|
||||||
|
|
||||||
|
- **`clear()`**
|
||||||
|
清空控件中的所有 HTML 内容。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
Html 控件不触发任何默认交互事件(如点击、输入等),但可以通过绑定父级容器或其他控件来监听 DOM 事件。若需响应内部元素的事件,建议使用 `binds` 绑定到具体操作目标。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "html_welcome", // 控件唯一标识
|
||||||
|
"widgettype": "Html", // 控件类型:Html
|
||||||
|
"options": {
|
||||||
|
"html": "<h1 style='color: blue;'>欢迎使用 Bricks.js</h1><p>这是一个使用 <strong>Html</strong> 控件插入的富文本内容。</p>"
|
||||||
|
// html 字段指定要渲染的 HTML 字符串
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "html_welcome",
|
||||||
|
"event": "click",
|
||||||
|
"target": "html_welcome",
|
||||||
|
"script": "console.log('用户点击了 Html 控件区域');",
|
||||||
|
"conform": {
|
||||||
|
"title": "确认操作",
|
||||||
|
"message": "你确定要查看控制台吗?",
|
||||||
|
"confirmText": "确定",
|
||||||
|
"cancelText": "取消"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - 此例创建了一个 ID 为 `html_welcome` 的 Html 控件。
|
||||||
|
> - `options.html` 中定义了带样式的标题和段落文本。
|
||||||
|
> - 使用 `binds` 监听点击事件,当用户点击该控件时,弹出确认对话框并输出日志到浏览器控制台。
|
||||||
|
> - 注意:由于是普通控件,不能包含 `subwidgets` 子控件数组。
|
||||||
136
docs/ai/iconbarpage.md
Normal file
136
docs/ai/iconbarpage.md
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# IconbarPage
|
||||||
|
|
||||||
|
**用途**:`IconbarPage` 是一个容器控件,用于构建具有图标工具栏(IconTextBar)和内容区域的页面布局。工具栏可放置在页面顶部或底部,点击工具栏中的图标按钮会动态加载并显示对应的内容模块。常用于导航式界面设计,如管理后台、多标签页应用等。
|
||||||
|
|
||||||
|
**类型**:容器控件,继承自 `bricks.VBox`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `constructor(opts)`
|
||||||
|
构造函数,初始化布局结构。根据 `opts.bar_at` 决定工具栏位置(top/bottom),创建 `IconTextBar` 工具栏和 `Filler` 内容容器,并绑定命令事件。
|
||||||
|
|
||||||
|
- `command_handle(event)`
|
||||||
|
工具栏触发 `'command'` 事件时的处理函数,接收选中工具项信息,并调用 `show_content` 切换内容。
|
||||||
|
|
||||||
|
- `show_content(tool)`
|
||||||
|
异步方法,根据传入的 `tool` 配置动态构建其 `content` 对应的控件,并替换当前内容区域的子控件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `'command'`
|
||||||
|
当用户点击工具栏上的某个工具项时,由 `IconTextBar` 触发此事件,携带 `tool` 数据作为参数,被 `command_handle` 捕获用于切换内容。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "main_iconbar_page",
|
||||||
|
"widgettype": "IconbarPage",
|
||||||
|
"options": {
|
||||||
|
"bar_at": "top", // 可选 'top' 或 'bottom',指定工具栏位置
|
||||||
|
"bar_opts": {
|
||||||
|
"margin": "5px", // 工具栏外边距
|
||||||
|
"rate": 1, // 布局比例
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"name": "dashboard",
|
||||||
|
"icon": "fa fa-tachometer", // 图标类名(如 Font Awesome)
|
||||||
|
"label": "仪表盘", // 显示文本(可选)
|
||||||
|
"tip": "进入系统仪表盘", // 提示文字
|
||||||
|
"dynsize": false, // 是否动态调整大小
|
||||||
|
"rate": 1,
|
||||||
|
"content": {
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "欢迎来到仪表盘页面!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "users",
|
||||||
|
"icon": "fa fa-users",
|
||||||
|
"label": "用户管理",
|
||||||
|
"tip": "管理所有用户信息",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "/widgets/users.ui", // 远程加载用户管理界面
|
||||||
|
"method": "GET",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "settings",
|
||||||
|
"icon": "fa fa-cog",
|
||||||
|
"label": "系统设置",
|
||||||
|
"tip": "配置系统参数",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "这里是系统设置页面"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"text": "保存设置"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "main_iconbar_page",
|
||||||
|
"event": "click",
|
||||||
|
"target": "main_iconbar_page",
|
||||||
|
"script": "alert('设置已保存')",
|
||||||
|
"conform": {
|
||||||
|
"title": "确认保存",
|
||||||
|
"message": "您确定要保存这些设置吗?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subwidgets": [], // 此控件自身不在此处定义子控件,而是通过 bar_opts.tools 动态加载
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "main_iconbar_page",
|
||||||
|
"event": "init",
|
||||||
|
"target": "main_iconbar_page",
|
||||||
|
"method": "show_content",
|
||||||
|
"params": {
|
||||||
|
"tool": {
|
||||||
|
"content": {
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "初始化默认内容"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - `IconbarPage` 使用 `bar_opts.tools` 数组定义多个功能入口,每个 `tool` 包含一个 `content` 字段,描述要加载的子界面。
|
||||||
|
> - `urlwidget` 类型可用于懒加载远程 `.ui` 文件,实现按需加载模块。
|
||||||
|
> - 通过 `binds` 绑定初始化行为,可在页面加载后自动显示默认内容。
|
||||||
|
> - `conform` 提供操作前的确认弹窗,增强用户体验与安全性。
|
||||||
146
docs/ai/iframe.md
Normal file
146
docs/ai/iframe.md
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# Iframe
|
||||||
|
|
||||||
|
Iframe 是一个容器控件,继承自 `bricks.Layout`,属于普通控件(虽然继承自容器类 Layout,但通常不用于放置子控件,而是嵌入外部网页内容)。该控件用于在当前页面中嵌入一个 `<iframe>` 元素,加载并显示指定 URL 的网页内容。适用于需要集成第三方页面、展示帮助文档或嵌入管理系统子模块的场景。
|
||||||
|
|
||||||
|
**类型:** 普通控件(继承自 `Layout`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `create()`
|
||||||
|
创建底层 DOM 元素(`<iframe>`),并在构造函数中设置其 `src` 属性为传入的 `url` 参数。
|
||||||
|
|
||||||
|
- `setValue(url)`
|
||||||
|
动态更新 iframe 的 `src`,实现页面内容切换。
|
||||||
|
|
||||||
|
- `getValue()`
|
||||||
|
返回当前 iframe 的 `src` 地址。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
Iframe 控件本身不定义自定义事件,但可监听原生 iframe 的事件,如:
|
||||||
|
|
||||||
|
- `'load'`:当 iframe 内容加载完成时触发。
|
||||||
|
- 自定义事件可通过 `binds` 机制绑定和派发。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "helpFrame", // 控件唯一标识
|
||||||
|
"widgettype": "Iframe", // 控件类型,必须为注册过的名称
|
||||||
|
"options": {
|
||||||
|
"url": "/docs/intro.html", // 要嵌入的网页地址
|
||||||
|
"height": "600px", // 可选:设置高度,默认为 '100%'
|
||||||
|
"width": "100%" // 可选:宽度,默认为父容器宽度
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method", // 执行目标控件的方法
|
||||||
|
"wid": "refreshBtn", // 触发组件 ID(例如一个按钮)
|
||||||
|
"event": "click", // 监听点击事件
|
||||||
|
"target": "helpFrame", // 目标是当前 iframe
|
||||||
|
"method": "setValue", // 调用 setValue 方法
|
||||||
|
"params": {
|
||||||
|
"value": "/docs/latest.html" // 新的 URL 值
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script", // 执行脚本
|
||||||
|
"wid": "logLoad",
|
||||||
|
"event": "load", // 当 iframe 加载完成后
|
||||||
|
"target": "helpFrame",
|
||||||
|
"script": "console.log('Iframe content loaded:', wid);",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `widgettype` 必须与 Bricks 注册表中的名称一致(如 `Iframe`)。
|
||||||
|
> - `options.url` 是必需参数,决定 iframe 显示的内容。
|
||||||
|
> - 使用 `binds` 可实现动态控制 iframe 内容更新或响应加载状态。
|
||||||
|
> - 若需传递参数给远程页面,可在 `url` 中附加查询字符串。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# NewWindow
|
||||||
|
|
||||||
|
NewWindow 是一个普通控件,继承自 `bricks.JsWidget`,用于在用户交互时打开一个新的浏览器窗口或标签页。常用于跳转到外部系统、弹出帮助页面或导出报表等场景。
|
||||||
|
|
||||||
|
**类型:** 普通控件(非容器,无子控件)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- 构造函数自动调用 `window.open()` 打开新窗口。
|
||||||
|
- 不提供额外方法,行为完全由初始化参数决定。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
NewWindow 控件不支持事件绑定(因为它不渲染任何可见 DOM 元素),其行为是一次性执行打开窗口操作。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "openHelpWindow",
|
||||||
|
"widgettype": "NewWindow", // 控件类型
|
||||||
|
"options": {
|
||||||
|
"url": "https://example.com/help", // 要打开的 URL
|
||||||
|
"name": "help_window", // 窗口名称(可选)
|
||||||
|
"features": "width=800,height=600" // 窗口特性(可选,传给 window.open)
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks", // 使用 bricks 动作创建控件
|
||||||
|
"wid": "helpBtn", // 绑定到某个按钮的点击
|
||||||
|
"event": "click",
|
||||||
|
"target": "Popup", // 特殊目标:弹出层(此处实际是新开窗口)
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "NewWindow",
|
||||||
|
"options": {
|
||||||
|
"url": "https://example.com/tutorial",
|
||||||
|
"name": "_blank"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `NewWindow` 不会在当前页面渲染任何元素,仅在触发时打开新窗口。
|
||||||
|
> - 通常通过其他控件(如按钮)的事件来触发。
|
||||||
|
> - `target: "Popup"` 配合 `actiontype: "bricks"` 实现动态打开新窗口的行为。
|
||||||
|
> - 更常见的是直接使用 `actiontype: "newwindow"`(如果框架支持),但此处通过控件方式实现兼容逻辑。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
💡 **补充建议:**
|
||||||
|
|
||||||
|
尽管 `NewWindow` 被实现为一个控件,但在实际使用中更推荐使用 `actiontype: "newwindow"` 类型的绑定来简化开发,例如:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"actiontype": "newwindow",
|
||||||
|
"wid": "btnTutorial",
|
||||||
|
"event": "click",
|
||||||
|
"url": "https://example.com/tutorial",
|
||||||
|
"name": "tutorial"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这比注册控件更轻量,除非你需要将其作为组件复用或进行复杂封装。
|
||||||
243
docs/ai/image.md
Normal file
243
docs/ai/image.md
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
# Image
|
||||||
|
|
||||||
|
用于在页面中显示图片,支持网络图片、Base64 编码图片以及错误时的默认图片回退机制。
|
||||||
|
**类型:普通控件(继承自 `JsWidget`)**
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `create()`
|
||||||
|
创建 `<img>` 元素并赋值给 `this.dom_element`。
|
||||||
|
|
||||||
|
- `set_url(url)`
|
||||||
|
设置图片的 `src` 属性,并绑定 `onerror` 事件以支持默认图回退。
|
||||||
|
|
||||||
|
- `set_default_url()`
|
||||||
|
当图片加载失败时,切换为默认图片(需配置 `default_url` 选项)。
|
||||||
|
|
||||||
|
- `base64()`
|
||||||
|
将当前图像绘制到 Canvas 并返回 PNG 格式的 Base64 数据 URL。
|
||||||
|
|
||||||
|
- `removeBase64Header(base64String)`
|
||||||
|
移除 Base64 字符串中的 MIME 头信息(如 `data:image/png;base64,`)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件。原生 `load` 和 `error` 事件可通过 DOM 监听。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "img_user_avatar",
|
||||||
|
"widgettype": "Image",
|
||||||
|
"options": {
|
||||||
|
"url": "https://example.com/avatar.png", // 图片地址
|
||||||
|
"default_url": "images/default-avatar.png" // 加载失败时显示的默认图
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "img_user_avatar",
|
||||||
|
"event": "click",
|
||||||
|
"script": "console.log('Image clicked:', data);",
|
||||||
|
"params": {},
|
||||||
|
"rtdata": {
|
||||||
|
"imageId": "img_user_avatar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "img_user_avatar",
|
||||||
|
"event": "load",
|
||||||
|
"target": "img_user_avatar",
|
||||||
|
"method": "base64",
|
||||||
|
"rtdata": {
|
||||||
|
"info": "Image loaded and converted to base64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ 注释说明:
|
||||||
|
> - `widgettype: "Image"` 表示使用注册的 Image 控件。
|
||||||
|
> - `options.url` 是必须项,指定图片源。
|
||||||
|
> - `default_url` 可选,用于容错处理。
|
||||||
|
> - 点击图片会执行一段脚本输出日志。
|
||||||
|
> - 图片成功加载后调用 `base64()` 方法获取其 Base64 编码数据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
|
||||||
|
图标控件,扩展自 `Image`,支持基于字符单位(charsize)动态调整尺寸,常用于界面小图标展示。
|
||||||
|
**类型:普通控件(继承自 `Image`)**
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `options_parse()`
|
||||||
|
解析图标大小相关参数,根据 `rate`、`cwidth`、`cheight` 和 `dynsize` 调整样式尺寸。
|
||||||
|
|
||||||
|
- `charsize_sizing()`
|
||||||
|
(继承自父类或 JsWidget 工具方法)根据 `bricks.app.charsize` 计算实际像素大小并设置宽高。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件,可监听原生事件如 `click`。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "icon_home",
|
||||||
|
"widgettype": "Icon",
|
||||||
|
"options": {
|
||||||
|
"url": "icons/home.svg", // 图标资源路径
|
||||||
|
"rate": 1.5, // 相对于基础字符尺寸的比例
|
||||||
|
"cwidth": 1, // 占据字符宽度数
|
||||||
|
"cheight": 1, // 占据字符高度数
|
||||||
|
"dynsize": true // 是否启用动态尺寸适配
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "icon_home",
|
||||||
|
"event": "click",
|
||||||
|
"target": "SidebarMenu",
|
||||||
|
"dispatch_event": "navigate",
|
||||||
|
"params": {
|
||||||
|
"page": "home"
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "Confirm Navigation",
|
||||||
|
"message": "Go to home page?",
|
||||||
|
"confirm_text": "Yes",
|
||||||
|
"cancel_text": "No"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ 注释说明:
|
||||||
|
> - `rate: 1.5` 表示图标为标准字符大小的 1.5 倍。
|
||||||
|
> - `dynsize: true` 启用响应式尺寸计算。
|
||||||
|
> - 点击图标将向目标控件 `SidebarMenu` 派发名为 `navigate` 的自定义事件,并携带参数 `{page: 'home'}`。
|
||||||
|
> - `conform` 提供用户确认弹窗,防止误操作。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# StatedIcon
|
||||||
|
|
||||||
|
状态图标控件,扩展自 `Icon`,支持多个状态(state)对应不同图标,适用于开关、模式切换等场景。
|
||||||
|
**类型:普通控件(继承自 `Icon`)**
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `options_parse()`
|
||||||
|
初始化状态系统,若未设置初始状态,则取第一个状态作为默认。
|
||||||
|
|
||||||
|
- `set_state(state)`
|
||||||
|
切换图标状态,查找匹配的状态对象并更新 `url`,重新渲染图标。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件,可通过 `binds` 触发状态变更。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "icon_power",
|
||||||
|
"widgettype": "StatedIcon",
|
||||||
|
"options": {
|
||||||
|
"state": "off", // 当前状态
|
||||||
|
"states": [ // 状态列表
|
||||||
|
{
|
||||||
|
"state": "on",
|
||||||
|
"url": "icons/power-on.svg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state": "off",
|
||||||
|
"url": "icons/power-off.svg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rate": 2,
|
||||||
|
"cwidth": 1,
|
||||||
|
"cheight": 1
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "icon_power",
|
||||||
|
"event": "click",
|
||||||
|
"target": "icon_power",
|
||||||
|
"method": "set_state",
|
||||||
|
"params": {
|
||||||
|
"state": "=this.state === 'on' ? 'off' : 'on'" // 动态翻转状态
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "registerfunction",
|
||||||
|
"wid": "icon_power",
|
||||||
|
"event": "click",
|
||||||
|
"rfname": "logUserAction",
|
||||||
|
"params": {
|
||||||
|
"action": "toggle_power",
|
||||||
|
"targetId": "icon_power",
|
||||||
|
"fromState": "=this.state",
|
||||||
|
"toState": "=this.state === 'on' ? 'off' : 'on'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ 注释说明:
|
||||||
|
> - `states` 定义了两个状态 `"on"` 和 `"off"`,分别对应不同的图标。
|
||||||
|
> - 初始状态为 `"off"`。
|
||||||
|
> - 点击时通过 `method` 调用自身 `set_state` 方法实现状态翻转。
|
||||||
|
> - 使用 `registerfunction` 调用全局函数 `logUserAction` 记录用户行为。
|
||||||
|
> - `=` 开头的字符串表示表达式求值(运行时计算),是 bricks 支持的动态语法扩展。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# BlankIcon
|
||||||
|
|
||||||
|
空白占位图标,不显示任何图像,仅用于布局占位,但支持与 `Icon` 一致的尺寸控制逻辑。
|
||||||
|
**类型:普通控件(继承自 `JsWidget`)**
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- 构造函数中调用 `charsize_sizing()` 实现基于字符单位的尺寸控制。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "placeholder_icon",
|
||||||
|
"widgettype": "BlankIcon",
|
||||||
|
"options": {
|
||||||
|
"cwidth": 2, // 占据 2 个字符宽度
|
||||||
|
"cheight": 1, // 占据 1 个字符高度
|
||||||
|
"rate": 1, // 尺寸比例
|
||||||
|
"dynsize": true // 启用动态尺寸
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ 注释说明:
|
||||||
|
> - `BlankIcon` 不创建图像元素,仅作为空白容器参与布局。
|
||||||
|
> - 常用于对齐或响应式布局中保持视觉一致性。
|
||||||
|
> - 支持与其他图标相同的 `cwidth`/`cheight`/`rate` 参数体系,便于统一管理 UI 尺寸规范。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 📌 **总结提示**:
|
||||||
|
> 所有控件均通过 `bricks.Factory.register()` 注册后方可使用;
|
||||||
|
> 在 `.ui` 文件中编写 JSON 结构即可声明式构建界面;
|
||||||
|
> `binds` 提供强大的交互能力,结合 `script`、`method`、`event` 等动作类型可灵活控制应用逻辑。
|
||||||
741
docs/ai/input.md
Normal file
741
docs/ai/input.md
Normal file
@ -0,0 +1,741 @@
|
|||||||
|
# UiStr
|
||||||
|
|
||||||
|
用于创建一个单行文本输入控件,用户可以输入或编辑字符串内容。该控件继承自 `UiType`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `getValue()`:返回包含当前输入值的对象,格式为 `{name: value}`。
|
||||||
|
- `setValue(v)`:设置输入框的值。
|
||||||
|
- `reset()`:重置输入框为初始值(`value` 或 `defaultValue`)。
|
||||||
|
- `focus()`:使输入框获得焦点。
|
||||||
|
- `set_disabled(f)`:启用/禁用输入框。
|
||||||
|
- `set_readonly(f)`:设置输入框是否只读。
|
||||||
|
- `set_required(f)`:设置是否为必填项。
|
||||||
|
- `resultValue()`:获取实际的字符串值。
|
||||||
|
- `set_formdata(formdata)`:将当前值添加到 `FormData` 对象中,用于表单提交。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:当输入内容发生变化时触发,携带数据为 `{name: value}`。
|
||||||
|
- `blur`:当输入框失去焦点时触发。
|
||||||
|
- `focus`:当输入框获得焦点时触发。
|
||||||
|
- `keydown`:当在输入框中按下键盘键时触发,若按 Enter 键会派发 `blur` 事件。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "username_input",
|
||||||
|
"widgettype": "UiStr",
|
||||||
|
"options": {
|
||||||
|
"name": "username", // 表单字段名
|
||||||
|
"value": "", // 初始值
|
||||||
|
"defaultValue": "请输入用户名", // 默认提示性值
|
||||||
|
"align": "left", // 文本对齐方式:left, center, right
|
||||||
|
"length": 50, // 最大字符数
|
||||||
|
"minlength": 2, // 最小字符数
|
||||||
|
"placeholder": "请输入用户名", // 占位符文本(支持国际化)
|
||||||
|
"width": "300px", // 控件宽度
|
||||||
|
"readonly": false, // 是否只读
|
||||||
|
"required": true, // 是否必填
|
||||||
|
"css": "custom-input-class" // 自定义CSS类名
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "username_input",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "submit_button",
|
||||||
|
"method": "set_disabled",
|
||||||
|
"params": {
|
||||||
|
"f": false
|
||||||
|
},
|
||||||
|
"conform": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "username_input",
|
||||||
|
"event": "blur",
|
||||||
|
"target": "logger",
|
||||||
|
"script": "console.log('用户输入了:', params);",
|
||||||
|
"rtdata": {
|
||||||
|
"params": "=getValue(username_input)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 此控件是一个基础文本输入框,常用于登录、注册等表单场景。
|
||||||
|
> - `binds` 中第一个绑定表示:当输入内容变化时,启用“提交按钮”。
|
||||||
|
> - 第二个绑定表示:当失去焦点时,通过脚本打印当前输入值。
|
||||||
|
> - `=getValue(widgetId)` 是 Bricks 支持的运行时数据表达式语法,用于动态获取其他控件的值。
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiPassword
|
||||||
|
|
||||||
|
用于创建密码输入框,隐藏用户输入内容。该控件继承自 `UiStr`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- 继承自 `UiStr` 的所有方法(如 `getValue`, `setValue`, `reset` 等)。
|
||||||
|
- `resultValue()`:返回明文密码字符串(注意安全处理)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:输入内容变更时触发。
|
||||||
|
- `blur`:失去焦点时触发。
|
||||||
|
- `focus`:获得焦点时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "password_input",
|
||||||
|
"widgettype": "UiPassword",
|
||||||
|
"options": {
|
||||||
|
"name": "password",
|
||||||
|
"value": "",
|
||||||
|
"placeholder": "请输入密码",
|
||||||
|
"required": true,
|
||||||
|
"length": 20,
|
||||||
|
"width": "100%"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "password_input",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "strength_checker",
|
||||||
|
"dispatch_event": "check_strength",
|
||||||
|
"rtdata": {
|
||||||
|
"password": "=getValue(password_input)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 使用 `UiPassword` 可确保输入内容以掩码形式显示。
|
||||||
|
> - 绑定事件将密码值传递给“强度检测器”控件进行实时校验。
|
||||||
|
> - 安全建议:避免在日志中直接输出密码明文。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiInt
|
||||||
|
|
||||||
|
用于输入整数的控件,基于 `UiStr` 扩展,自动限制输入为数字。该控件继承自 `UiStr`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `resultValue()`:返回整数类型值(使用 `parseInt` 转换)。
|
||||||
|
- 其他方法均继承自 `UiStr`。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:数值改变时触发。
|
||||||
|
- `blur` / `focus`:焦点相关事件。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "age_input",
|
||||||
|
"widgettype": "UiInt",
|
||||||
|
"options": {
|
||||||
|
"name": "age",
|
||||||
|
"value": 18,
|
||||||
|
"placeholder": "请输入年龄",
|
||||||
|
"minlength": 1,
|
||||||
|
"length": 3,
|
||||||
|
"width": "100px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "age_input",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "user_form",
|
||||||
|
"method": "validateField",
|
||||||
|
"params": {
|
||||||
|
"field": "age"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 输入仅允许数字字符。
|
||||||
|
> - `resultValue()` 返回 `Number` 类型,便于后续逻辑判断。
|
||||||
|
> - 常用于需要整数输入的表单字段(如年龄、数量等)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiFloat
|
||||||
|
|
||||||
|
用于输入浮点数的控件,继承自 `UiInt`,支持小数输入和精度控制。该控件属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `resultValue()`:返回浮点数(使用 `parseFloat` 转换)。
|
||||||
|
- `setValue(v)`:设置值并更新 DOM 显示。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:浮点数更改后触发。
|
||||||
|
- `blur` / `focus`:同上。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "price_input",
|
||||||
|
"widgettype": "UiFloat",
|
||||||
|
"options": {
|
||||||
|
"name": "price",
|
||||||
|
"value": 0.00,
|
||||||
|
"dec_len": 2, // 小数位数,默认为2
|
||||||
|
"placeholder": "请输入价格",
|
||||||
|
"width": "150px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "price_input",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "total_calculator",
|
||||||
|
"mode": "append",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "=getValue(price_input) * 1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `dec_len` 控制小数点后位数,并影响 HTML `step` 属性。
|
||||||
|
> - 支持数学表达式绑定,例如计算含税总价。
|
||||||
|
> - 推荐与服务端双重验证结合使用,防止非法输入。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiDate
|
||||||
|
|
||||||
|
日期选择控件,提供原生日期选择器界面。继承自 `UiStr`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `opts_setup()`:初始化 `<input type="date">` 并设置最大最小日期。
|
||||||
|
- `resultValue()`:返回字符串格式的日期(如 `"2025-04-05"`),空值返回 `null`。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:日期变更时触发。
|
||||||
|
- `blur` / `focus`:焦点事件。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "birthday_input",
|
||||||
|
"widgettype": "UiDate",
|
||||||
|
"options": {
|
||||||
|
"name": "birthday",
|
||||||
|
"value": "1990-01-01",
|
||||||
|
"min_date": "1900-01-01",
|
||||||
|
"max_date": "2025-12-31",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "birthday_input",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "age_display",
|
||||||
|
"script": "const birth = new Date(params.birthday); const age = new Date().getFullYear() - birth.getFullYear(); bricks.getWidget('age_label').setValue('年龄: ' + age + '岁');",
|
||||||
|
"rtdata": {
|
||||||
|
"params": "=getValue(birthday_input)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 浏览器原生日期选择器兼容性良好。
|
||||||
|
> - `min_date` 和 `max_date` 可限制选择范围。
|
||||||
|
> - 示例中通过脚本动态计算并显示年龄。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiCheck
|
||||||
|
|
||||||
|
复选框控件(单个),用于布尔状态切换(true/false)。该控件继承自 `UiType`,是**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `setValue(v)`:设置为选中(true)或未选中(false)。
|
||||||
|
- `resultValue()`:返回布尔值。
|
||||||
|
- `set_value_from_input(e)`:内部方法,响应图标状态变化。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:状态切换时触发,携带 `{name: true|false}` 数据。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "agree_check",
|
||||||
|
"widgettype": "UiCheck",
|
||||||
|
"options": {
|
||||||
|
"name": "agree",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "agree_check",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "submit_button",
|
||||||
|
"method": "set_disabled",
|
||||||
|
"params": {
|
||||||
|
"f": "=!getValue(agree_check).agree"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 使用 SVG 图标实现美观的勾选效果。
|
||||||
|
> - 绑定逻辑:只有用户勾选“同意”后,“提交”按钮才可用。
|
||||||
|
> - `= !getValue(...)` 为 Bricks 支持的表达式语法。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiCheckBox
|
||||||
|
|
||||||
|
多选/单选框组控件,支持从本地数据或远程 URL 加载选项列表。继承自 `UiType`,属于**容器控件**(可包含多个子控件)。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `build_checkboxs()`:根据数据构建多个 `UiCheck` 子控件。
|
||||||
|
- `load_data_onfly()`:异步加载远程数据。
|
||||||
|
- `set_value_from_input(event)`:处理任一选项变化,更新 `this.value` 数组。
|
||||||
|
- `setValue(v)`:设置已选值(支持数组或单值)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:任一选项变化时触发,返回 `{name: [values]}` 或 `{name: value}`。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "hobby_checkbox",
|
||||||
|
"widgettype": "UiCheckBox",
|
||||||
|
"options": {
|
||||||
|
"name": "hobbies",
|
||||||
|
"label": "兴趣爱好",
|
||||||
|
"textField": "text",
|
||||||
|
"valueField": "id",
|
||||||
|
"data": [
|
||||||
|
{ "id": "reading", "text": "阅读" },
|
||||||
|
{ "id": "sports", "text": "运动" },
|
||||||
|
{ "id": "music", "text": "音乐" }
|
||||||
|
],
|
||||||
|
"multicheck": true
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "hobby_checkbox",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "preference_analyzer",
|
||||||
|
"dispatch_event": "update_preferences",
|
||||||
|
"rtdata": {
|
||||||
|
"hobbies": "=getValue(hobby_checkbox)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 若 `multicheck: true`,则允许多选;否则为单选。
|
||||||
|
> - 支持静态 `data` 或动态 `dataurl` 加载选项。
|
||||||
|
> - 常用于表单中的多项选择题或偏好设置。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiCode
|
||||||
|
|
||||||
|
下拉选择控件(`<select>`),用于从预定义选项中选择一个值。继承自 `UiType`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `build_options(data)`:根据数据重建 `<option>` 列表。
|
||||||
|
- `load_data(params)`:从远程 URL 异步加载数据。
|
||||||
|
- `get_data(event)`:响应外部事件重新加载数据。
|
||||||
|
- `setValue(v)`:设置选中项的值。
|
||||||
|
- `resultValue()`:返回当前选中的值。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:选项变更时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "country_select",
|
||||||
|
"widgettype": "UiCode",
|
||||||
|
"options": {
|
||||||
|
"name": "country",
|
||||||
|
"textField": "name_zh",
|
||||||
|
"valueField": "code",
|
||||||
|
"nullable": true,
|
||||||
|
"dataurl": "/api/countries",
|
||||||
|
"method": "GET",
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "country_select",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "province_container",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/ui/province_list.ui",
|
||||||
|
"params": {
|
||||||
|
"country_code": "=getValue(country_select).country"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 支持从 `/api/countries` 动态加载国家列表。
|
||||||
|
> - `nullable: true` 表示允许空选项(第一项为空)。
|
||||||
|
> - 更改国家后,通过 `urlwidget` 加载对应省份 UI 片段,实现联动。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiText
|
||||||
|
|
||||||
|
多行文本输入控件(`<textarea>`),适用于长文本输入。继承自 `UiType`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `handle_enter()`:拦截回车键,插入换行符。
|
||||||
|
- `handle_tab_indent(erase)`:支持 Tab 缩进与 Shift+Tab 反缩进(每次4空格)。
|
||||||
|
- `key_handle(e)`:键盘事件处理器。
|
||||||
|
- `set_editor_focus(editor, pos)`:异步聚焦并定位光标。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:内容变更时触发。
|
||||||
|
- `keydown`:按键事件,支持自定义行为。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "note_textarea",
|
||||||
|
"widgettype": "UiText",
|
||||||
|
"options": {
|
||||||
|
"name": "note",
|
||||||
|
"value": "",
|
||||||
|
"rows": 8,
|
||||||
|
"cols": 60,
|
||||||
|
"placeholder": "请输入备注信息...",
|
||||||
|
"width": "100%",
|
||||||
|
"height": "200px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "note_textarea",
|
||||||
|
"event": "input",
|
||||||
|
"target": "char_counter",
|
||||||
|
"script": "bricks.getWidget('char_count_label').setValue('已输入 ' + params.note.length + ' 字');",
|
||||||
|
"rtdata": {
|
||||||
|
"params": "=getValue(note_textarea)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 支持 Tab 缩进功能,适合代码或结构化文本输入。
|
||||||
|
> - 实时统计字数并更新显示。
|
||||||
|
> - 高度可配置,适合各种富文本输入场景。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiSearch
|
||||||
|
|
||||||
|
搜索选择控件,点击图标弹出远程窗口选择数据。继承自 `HBox`,属于**容器控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `open_search_window(event)`:打开弹窗并加载远程表格。
|
||||||
|
- `set_data(event)`:接收选中行数据并填充。
|
||||||
|
- `resultValue()`:返回选中的 `valueField` 值。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:选择完成后触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "customer_search",
|
||||||
|
"widgettype": "UiSearch",
|
||||||
|
"options": {
|
||||||
|
"name": "customer_id",
|
||||||
|
"text": "请选择客户",
|
||||||
|
"search_url": "/ui/customer_picker.ui",
|
||||||
|
"valueField": "id",
|
||||||
|
"textField": "name",
|
||||||
|
"search_event": "row_selected",
|
||||||
|
"popup_options": {
|
||||||
|
"title": "选择客户",
|
||||||
|
"width": "80%",
|
||||||
|
"height": "70%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "customer_search",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "order_form",
|
||||||
|
"dispatch_event": "customer_selected",
|
||||||
|
"rtdata": {
|
||||||
|
"customer_id": "=getValue(customer_search)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 用户点击放大镜图标,弹出 `/ui/customer_picker.ui` 页面。
|
||||||
|
> - 表格组件监听 `row_selected` 事件并将结果传回。
|
||||||
|
> - 实现“所见即所得”的复杂数据选择模式,广泛用于 ERP、CRM 系统。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiFile
|
||||||
|
|
||||||
|
文件上传控件,支持拖拽上传和点击选择。继承自 `VBox`,属于**容器控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `handleFileSelect(event)`:处理手动选择文件。
|
||||||
|
- `dropHandle(event)`:处理拖放文件。
|
||||||
|
- `set_input_file(files)`:程序化设置文件输入。
|
||||||
|
- `resultValue()`:返回 File 对象或 FileList。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:文件选择或拖入后触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "attachment_upload",
|
||||||
|
"widgettype": "UiFile",
|
||||||
|
"options": {
|
||||||
|
"name": "file",
|
||||||
|
"accept": "application/pdf",
|
||||||
|
"multiple": false,
|
||||||
|
"width": "100%"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "attachment_upload",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "upload_service",
|
||||||
|
"method": "startUpload",
|
||||||
|
"params": {
|
||||||
|
"file": "=resultValue(attachment_upload)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `accept` 限制只能上传 PDF 文件。
|
||||||
|
> - 支持拖拽上传,提升用户体验。
|
||||||
|
> - 绑定调用上传服务开始传输文件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiImage
|
||||||
|
|
||||||
|
图像上传控件,扩展自 `UiFile`,增加拍照按钮和预览功能。属于**容器控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `take_photo()`:调起摄像头拍摄。
|
||||||
|
- `accept_photo(camera, event)`:接收拍摄图片并设置值。
|
||||||
|
- `show_image()` / `_show_image()`:显示图片预览(支持 File 或 URL)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:图片选择或拍摄完成后触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "avatar_uploader",
|
||||||
|
"widgettype": "UiImage",
|
||||||
|
"options": {
|
||||||
|
"name": "avatar",
|
||||||
|
"width": "300px",
|
||||||
|
"height": "auto"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "avatar_uploader",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "profile_preview",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Image",
|
||||||
|
"options": {
|
||||||
|
"url": "=resultValue(avatar_uploader)",
|
||||||
|
"width": "100px",
|
||||||
|
"height": "100px",
|
||||||
|
"style": "border-radius: 50%;"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 用户可通过上传或拍照方式设置头像。
|
||||||
|
> - 实时预览上传的图像。
|
||||||
|
> - 结合 `bricks` action 实现动态图像替换。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiAudio
|
||||||
|
|
||||||
|
音频上传与录制控件,支持麦克风录音。继承自 `UiFile`,属于**容器控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `open_recorder()`:打开音频录制器。
|
||||||
|
- `accept_audio(recorder, event)`:接收录音文件。
|
||||||
|
- `show_audio()` / `_show_audio()`:播放音频预览。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:音频文件上传或录制完成时触发。
|
||||||
|
- `record_end`:录音结束事件(来自 `SysAudioRecorder`)。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "voice_note",
|
||||||
|
"widgettype": "UiAudio",
|
||||||
|
"options": {
|
||||||
|
"name": "audio_clip",
|
||||||
|
"width": "100%"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "voice_note",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "transcription_engine",
|
||||||
|
"dispatch_event": "start_transcribe",
|
||||||
|
"rtdata": {
|
||||||
|
"audio_file": "=resultValue(voice_note)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 提供“上传”和“录音”两种方式获取音频。
|
||||||
|
> - 录音完成后自动插入预览播放器。
|
||||||
|
> - 可与语音识别服务集成,实现语音转文字。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# UiVideo
|
||||||
|
|
||||||
|
视频上传与录制控件,支持摄像头录制视频。继承自 `UiFile`,属于**容器控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `open_recorder()`:启动视频录制窗口。
|
||||||
|
- `accept_video()`:接收录制完成的视频文件。
|
||||||
|
- `show_video()` / `_show_video()`:显示视频预览。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`:视频文件上传或录制完成时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "video_introduction",
|
||||||
|
"widgettype": "UiVideo",
|
||||||
|
"options": {
|
||||||
|
"name": "intro_video",
|
||||||
|
"width": "100%"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "video_introduction",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "video_thumbnail_generator",
|
||||||
|
"method": "extractThumbnail",
|
||||||
|
"params": {
|
||||||
|
"video": "=resultValue(video_introduction)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 支持上传 `.mp4` 等常见格式视频。
|
||||||
|
> - 内建录制功能,方便移动端使用。
|
||||||
|
> - 可配合后台服务提取封面图或进行转码。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> ✅ 所有控件均遵循 Bricks.js 的 JSON 规范,支持模块化开发、事件驱动、动态加载与国际化。
|
||||||
|
> 💡 推荐结合 `.ui` 文件组织界面,利用 `urlwidget` 实现懒加载与微前端架构。
|
||||||
73
docs/ai/keypress.md
Normal file
73
docs/ai/keypress.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# KeyPress
|
||||||
|
|
||||||
|
KeyPress 是一个用于监听全局键盘按键事件的容器控件,能够在用户按下任意键时动态显示按下的键名。该控件继承自 `VBox`,属于**容器控件**,可容纳子控件(如文本提示控件),适用于需要键盘交互反馈的场景,例如调试工具、快捷键提示等。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`key_handler(event)`**
|
||||||
|
键盘事件处理函数,接收 `keydown` 事件对象,提取 `event.key` 值,并更新界面显示当前按键。
|
||||||
|
|
||||||
|
- **`clear_widgets()`**
|
||||||
|
继承自 `VBox`,用于清空当前容器内的所有子控件,确保每次只显示最新的按键信息。
|
||||||
|
|
||||||
|
- **`add_widget(widget)`**
|
||||||
|
向容器中添加新的控件(如 `Text` 控件),用于展示按键内容。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`keydown`**
|
||||||
|
全局键盘按下事件,由 `bricks.app.bind` 绑定在应用级别,触发 `key_handler` 方法。
|
||||||
|
|
||||||
|
> 注意:此事件为全局监听,不依赖于焦点元素,适合实现全局快捷键功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "keypress_demo", // 控件唯一标识
|
||||||
|
"widgettype": "KeyPress", // 控件类型,必须为已注册的 'KeyPress'
|
||||||
|
"options": {}, // 构造参数,此处无特殊配置
|
||||||
|
"subwidgets": [] // 容器控件,初始无子控件,运行时动态添加
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释说明:
|
||||||
|
|
||||||
|
- `"id"`: 设置控件实例的唯一 ID,便于后续通过 ID 查找或绑定事件。
|
||||||
|
- `"widgettype"`: 必须与工厂注册名称一致(`bricks.Factory.register('KeyPress', ...)`)。
|
||||||
|
- `"options"`: 当前控件无需额外参数,保持空对象即可。
|
||||||
|
- `"subwidgets"`: 虽然是容器控件,但初始不预设子控件,实际子控件在 `key_handler` 中动态创建和插入。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 补充:如何使用此控件结合 binds 实现扩展行为?
|
||||||
|
|
||||||
|
假设你想在按下某个特定键(如 'Enter')时弹出确认窗口,可以通过外部绑定增强其行为。示例如下:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "keypress_with_bind",
|
||||||
|
"widgettype": "KeyPress",
|
||||||
|
"options": {},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "keypress_with_bind",
|
||||||
|
"event": "key_pressed", // 自定义事件,需在 KeyPress 中派发
|
||||||
|
"script": "async function({key}) { if (key === 'Enter') { alert('回车键被按下!'); } }",
|
||||||
|
"datawidget": "keypress_with_bind",
|
||||||
|
"datamethod": "getLastKey", // 需要在 KeyPress 中实现 getLastKey 方法获取最后按键
|
||||||
|
"rtdata": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ 提示:若需支持上述 bind 用法,建议扩展 `KeyPress` 类并添加 `getLastKey()` 方法及 `dispatchEvent` 派发自定义事件能力。
|
||||||
444
docs/ai/layout.md
Normal file
444
docs/ai/layout.md
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
# Layout
|
||||||
|
|
||||||
|
Layout 是 Bricks.js 框架中的基础容器控件,用于组织和管理子控件(subwidgets)。它是所有布局类控件的基类,支持键盘导航、动态添加/删除子控件、标题与描述渲染等功能。
|
||||||
|
**类型**:容器控件,继承自 `bricks.JsWidget`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `add_widget(w, index)` | 向容器中添加一个控件,可指定插入位置;若未指定,则追加到末尾 |
|
||||||
|
| `remove_widget(w)` | 从容器中移除指定控件 |
|
||||||
|
| `clear_widgets()` | 清空容器内所有子控件 |
|
||||||
|
| `enable_key_select()` | 启用键盘选择功能,将该容器推入全局选择栈 |
|
||||||
|
| `disable_key_select()` | 禁用键盘选择,并从选择栈中弹出 |
|
||||||
|
| `select_next_item()` | 选中下一个可选控件(支持循环) |
|
||||||
|
| `select_previous_item()` | 选中上一个可选控件(支持循环) |
|
||||||
|
| `up_level()` | 键盘“返回”操作:退出当前层级 |
|
||||||
|
| `down_level()` | 键盘“进入”操作:进入下一层级的可选控件 |
|
||||||
|
| `enter_handler()` | 回车键处理:触发当前选中控件的 `click` 事件 |
|
||||||
|
| `key_handler(event)` | 键盘事件处理器,响应方向键与回车 |
|
||||||
|
| `build_title()` | 构建并添加标题控件(Title3) |
|
||||||
|
| `build_description()` | 构建并添加描述文本控件(Text) |
|
||||||
|
| `find_first_keyselectable_child()` | 查找第一个支持键盘选择的子控件 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 参数 |
|
||||||
|
|-------|--------|------|
|
||||||
|
| `on_parent` | 当控件被添加或从父容器中移除时触发 | parent: 当前父容器对象 |
|
||||||
|
| `element_resize` | 元素尺寸变化时触发(由 ResponsableBox 绑定使用) | params: 包含尺寸信息的对象 |
|
||||||
|
| `click` | 被 dispatch 触发时模拟点击行为 | - |
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "main_layout",
|
||||||
|
"widgettype": "Layout",
|
||||||
|
"options": {
|
||||||
|
"title": "主界面布局", // 显示标题(i18n 支持)
|
||||||
|
"description": "这是一个示例布局容器", // 描述文本
|
||||||
|
"keyselectable": true // 启用键盘导航
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "title_widget",
|
||||||
|
"widgettype": "Title3",
|
||||||
|
"options": {
|
||||||
|
"otext": "欢迎使用系统",
|
||||||
|
"i18n": true,
|
||||||
|
"dynsize": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "menu_container",
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"keyselectable": true
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "btn_home",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"otext": "首页",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_settings",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"otext": "设置",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_home",
|
||||||
|
"event": "click",
|
||||||
|
"target": "content_area",
|
||||||
|
"method": "loadPage",
|
||||||
|
"params": {
|
||||||
|
"page": "home"
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "确认跳转?",
|
||||||
|
"message": "是否要跳转到首页?",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_settings",
|
||||||
|
"event": "click",
|
||||||
|
"target": "content_area",
|
||||||
|
"method": "loadPage",
|
||||||
|
"params": {
|
||||||
|
"page": "settings"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "main_layout",
|
||||||
|
"event": "element_resize",
|
||||||
|
"target": "main_layout",
|
||||||
|
"dispatch_event": "reset_type"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - 使用 `Layout` 作为根容器,启用键盘选择 (`keyselectable`)。
|
||||||
|
> - 内部包含标题和一个垂直菜单 VBox,菜单项为按钮。
|
||||||
|
> - 通过 `binds` 实现按钮点击后调用目标控件的方法。
|
||||||
|
> - `conform` 字段用于在执行前弹出确认对话框。
|
||||||
|
> - `element_resize` 事件可用于响应式布局调整(如在 ResponsableBox 中使用)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# VBox
|
||||||
|
|
||||||
|
垂直布局容器,子控件按垂直方向排列。
|
||||||
|
**类型**:容器控件,继承自 `Layout`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
继承自 `Layout`,无额外独有方法。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
同 `Layout`
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "vertical_box",
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"keyselectable": true
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "label_welcome",
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "欢迎登录系统",
|
||||||
|
"i18n": true,
|
||||||
|
"css": "welcome-text"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "input_username",
|
||||||
|
"widgettype": "TextInput",
|
||||||
|
"options": {
|
||||||
|
"placeholder": "请输入用户名",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "input_password",
|
||||||
|
"widgettype": "PasswordInput",
|
||||||
|
"options": {
|
||||||
|
"placeholder": "请输入密码",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_login",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"otext": "登录",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_login",
|
||||||
|
"event": "click",
|
||||||
|
"target": "login_form_handler",
|
||||||
|
"method": "submit",
|
||||||
|
"datawidget": "input_username",
|
||||||
|
"datamethod": "getValue",
|
||||||
|
"dataparams": {},
|
||||||
|
"rtdata": {
|
||||||
|
"action": "/api/login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - `VBox` 自动应用 CSS 类 `vcontainer` 实现垂直布局。
|
||||||
|
> - 表单元素依次垂直排列。
|
||||||
|
> - 登录按钮绑定提交动作,获取输入框值并携带运行时数据发送请求。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# HBox
|
||||||
|
|
||||||
|
水平布局容器,子控件按水平方向排列。
|
||||||
|
**类型**:容器控件,继承自 `Layout`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
继承自 `Layout`
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
同 `Layout`
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "toolbar",
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "icon_home",
|
||||||
|
"widgettype": "Icon",
|
||||||
|
"options": {
|
||||||
|
"name": "home",
|
||||||
|
"size": "24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "text_title",
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "主页",
|
||||||
|
"i18n": true,
|
||||||
|
"css": "toolbar-title"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "spacer",
|
||||||
|
"widgettype": "Filler"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_refresh",
|
||||||
|
"widgettype": "IconButton",
|
||||||
|
"options": {
|
||||||
|
"icon": "refresh",
|
||||||
|
"tooltip": "刷新数据",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_more",
|
||||||
|
"widgettype": "MenuButton",
|
||||||
|
"options": {
|
||||||
|
"icon": "more_vert",
|
||||||
|
"menu": [
|
||||||
|
{ "text": "设置", "id": "settings", "i18n": true },
|
||||||
|
{ "text": "退出", "id": "logout", "i18n": true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - `HBox` 应用 `hcontainer` 样式实现水平排布。
|
||||||
|
> - 使用 `Filler` 占位实现右侧按钮靠右对齐。
|
||||||
|
> - 工具栏包含图标、文字、填充和操作按钮。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Filler
|
||||||
|
|
||||||
|
弹性填充控件,用于在布局中占据剩余空间,常用于对齐目的。
|
||||||
|
**类型**:容器控件(但通常不放置子控件),继承自 `Layout`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
无特殊方法,主要用于样式布局
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "footer_bar",
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "status",
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "就绪",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "flex_spacer",
|
||||||
|
"widgettype": "Filler"
|
||||||
|
// 占据中间空白区域
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_close",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"otext": "关闭",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - `Filler` 控件自动获得 `flex: 1` 特性(通过 CSS 类 `filler` 实现),撑开中间区域。
|
||||||
|
> - 实现左-中-右布局结构。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# ResponsableBox
|
||||||
|
|
||||||
|
响应式布局容器,能根据宽高比自动切换横竖排布模式。
|
||||||
|
**类型**:容器控件,继承自 `Layout`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|-------|------|
|
||||||
|
| `reset_type(event)` | 响应尺寸变化事件,根据宽高比切换 CSS 类实现布局反转 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 |
|
||||||
|
|-------|---------|
|
||||||
|
| `element_resize` | 尺寸改变时触发,由自身监听 |
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "responsive_panel",
|
||||||
|
"widgettype": "ResponsableBox",
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "sidebar",
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "sidebar"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "nav_item_1",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"otext": "仪表盘",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "nav_item_2",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"otext": "报表",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "main_content",
|
||||||
|
"widgettype": "Filler",
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "dynamic_view",
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "/views/home.json",
|
||||||
|
"method": "GET"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - 当宽度大于高度时,设为横向布局(`.hcontainer`);
|
||||||
|
> - 否则设为纵向布局(`.vcontainer`),实现移动端友好适配。
|
||||||
|
> - 结合 `urlwidget` 实现内容区动态加载。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# FHBox / FVBox
|
||||||
|
|
||||||
|
带 `flexWrap: nowrap` 的固定行/列布局容器。
|
||||||
|
- **FHBox**:水平不可换行容器
|
||||||
|
- **FVBox**:垂直不可换行容器
|
||||||
|
**类型**:容器控件,分别继承自 `HBox` 和 `VBox`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
无独有方法
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
同 `Layout`
|
||||||
|
|
||||||
|
## 源码例子(FHBox)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "fixed_toolbar",
|
||||||
|
"widgettype": "FHBox",
|
||||||
|
"options": {
|
||||||
|
"css": "no-wrap-toolbar"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{ "id": "btn_1", "widgettype": "Button", "options": { "otext": "新建" } },
|
||||||
|
{ "id": "btn_2", "widgettype": "Button", "options": { "otext": "编辑" } },
|
||||||
|
{ "id": "btn_3", "widgettype": "Button", "options": { "otext": "删除" } },
|
||||||
|
{ "id": "btn_4", "widgettype": "Button", "options": { "otext": "导出" } },
|
||||||
|
{ "id": "btn_5", "widgettype": "Button", "options": { "otext": "打印" } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - 使用 `FHBox` 防止工具栏按钮换行,超出部分可通过滚动查看。
|
||||||
|
> - 适用于需要保持一行显示的操作栏场景。
|
||||||
115
docs/ai/line.md
Normal file
115
docs/ai/line.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# ChartLine
|
||||||
|
|
||||||
|
ChartLine 是一个基于 ECharts 的折线图控件,用于可视化展示一组或多组数值型数据随某一维度(如时间、类别)的变化趋势。它是 **普通控件**,继承自 `bricks.EchartsExt`,属于 bricks 框架中用于数据可视化的扩展组件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`values_from_data(data, name)`**
|
||||||
|
从数据数组中提取指定字段的值,返回值数组,用于生成折线的数据点。
|
||||||
|
|
||||||
|
- **`lineinfo_from_data(data, name)`**
|
||||||
|
根据字段名生成单条折线的配置对象(包含名称和数据),供 ECharts 使用。
|
||||||
|
|
||||||
|
- **`setup_options(data)`**
|
||||||
|
核心方法,根据传入的数据和控件配置项(如 `nameField`, `valueFields`)动态构建完整的 ECharts 配置项(`option`),并返回。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
该控件本身不派发自定义业务事件,但作为 ECharts 实例,支持以下原生事件绑定:
|
||||||
|
|
||||||
|
- `'click'`:当用户点击图表中的某个数据点时触发。
|
||||||
|
- `'mouseover'`:鼠标悬停在图表元素上时触发。
|
||||||
|
- 可通过 `binds` 绑定这些事件,并结合 `dispatch_event` 或 `script` 做进一步处理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "chart_sales_trend",
|
||||||
|
"widgettype": "ChartLine",
|
||||||
|
"options": {
|
||||||
|
// 数据来源 URL,将从服务器获取原始数据
|
||||||
|
"data_url": "/api/sales/data",
|
||||||
|
"data_params": {
|
||||||
|
"period": "monthly",
|
||||||
|
"category": "electronics"
|
||||||
|
},
|
||||||
|
"method": "GET",
|
||||||
|
|
||||||
|
// 图表显示所需的关键字段配置
|
||||||
|
"nameField": "month", // X轴显示的维度字段(如月份)
|
||||||
|
"valueFields": [ // 多个要绘制的指标字段
|
||||||
|
"sales_amount",
|
||||||
|
"profit"
|
||||||
|
],
|
||||||
|
|
||||||
|
// 自定义 ECharts 选项扩展(可选)
|
||||||
|
"line_options": {
|
||||||
|
"tooltip": {
|
||||||
|
"formatter": "{b}: {c}"
|
||||||
|
},
|
||||||
|
"series": {
|
||||||
|
"smooth": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 初始静态数据(可选,若无 data_url 可直接使用)
|
||||||
|
"data": [
|
||||||
|
{ "month": "Jan", "sales_amount": 120, "profit": 30 },
|
||||||
|
{ "month": "Feb", "sales_amount": 140, "profit": 35 },
|
||||||
|
{ "month": "Mar", "sales_amount": 160, "profit": 40 },
|
||||||
|
{ "month": "Apr", "sales_amount": 150, "profit": 38 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 事件绑定:点击图表时弹出当前点击的数据信息
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "chart_sales_trend",
|
||||||
|
"event": "click",
|
||||||
|
"target": "chart_sales_trend",
|
||||||
|
"script": "async function({ params }) { console.log('点击了图表:', params); alert('你点击了: ' + params.name + ',数值: ' + params.value); }",
|
||||||
|
"params": {
|
||||||
|
"params": "=event.params" // 获取 ECharts 事件参数
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "chart_sales_trend",
|
||||||
|
"event": "refresh",
|
||||||
|
"target": "chart_sales_trend",
|
||||||
|
"method": "refreshData",
|
||||||
|
"params": {
|
||||||
|
"params": {
|
||||||
|
"period": "quarterly"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
>
|
||||||
|
> - `id`: 控件唯一标识符,在页面中必须唯一。
|
||||||
|
> - `widgettype`: 必须为已注册的控件类型,此处为 `"ChartLine"`。
|
||||||
|
> - `options.data_url`: 若提供,则控件会在初始化时自动发起请求获取数据。
|
||||||
|
> - `options.data_params`: 请求参数,与 `data_url` 配合使用。
|
||||||
|
> - `options.method`: HTTP 方法,默认为 GET。
|
||||||
|
> - `options.nameField`: 定义 X 轴使用的字段名(例如 “month”、“date”)。
|
||||||
|
> - `options.valueFields`: 定义需要绘制为折线的多个数值字段。
|
||||||
|
> - `options.data`: 可选的本地静态数据,优先级低于远程数据。
|
||||||
|
> - `binds[0]`: 监听图表的 click 事件,执行脚本打印或提示用户点击内容。
|
||||||
|
> - `binds[1]`: 支持调用控件自身的 `refreshData` 方法来刷新数据(例如切换时间段后重新加载)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
📌 **提示:**
|
||||||
|
此控件适合用于仪表盘、报表系统等需要动态展示趋势图的场景。配合 `urlwidget` 可实现按需加载不同图表模块,提升应用性能。
|
||||||
118
docs/ai/llm.md
Normal file
118
docs/ai/llm.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
以下是根据你提供的源码和文档规范,为 `bricks.LlmIO` 控件编写的 **Markdown 格式控件文档示例**。由于源码中注册了多个控件(如 `LlmMsgAudio`, `ModelOutput`, `LlmModel`, `LlmIO`),我们以 **`LlmIO` 为主控件进行完整示例编写**,其他控件可依此模板类推。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# LlmIO
|
||||||
|
|
||||||
|
用于构建多模型语言模型输入输出交互界面的容器控件,支持动态添加语言模型、配置知识库(KDB)、输入数据并分发给各模型处理,适用于聊天机器人、AI助手等场景。
|
||||||
|
类型:**容器控件**,继承自 `bricks.VBox`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|-------|------|
|
||||||
|
| `show_added_model(m)` | 将指定模型配置对象渲染为 `LlmModel` 实例并显示在顶部标题栏 |
|
||||||
|
| `open_search_models(event)` | 打开弹窗,通过 `Cols` 组件加载可用模型列表供用户选择 |
|
||||||
|
| `add_new_model(event)` | 处理模型选择事件,将新模型加入 `this.models` 并调用 `show_added_model` 显示 |
|
||||||
|
| `setup_kdb(event)` | 打开知识库配置弹窗,允许用户设置 KDB 参数及提示词模板 |
|
||||||
|
| `handle_kdb_setup(event)` | 接收表单提交的 KDB 配置并保存到 `this.kdb_setting` |
|
||||||
|
| `open_input_widget(event)` | 打开输入表单弹窗,供用户填写输入内容 |
|
||||||
|
| `handle_input(event)` | 处理输入提交,广播输入数据到所有已加载的 `LlmModel` 实例 |
|
||||||
|
| `show_input(params)` | 在输出区域显示用户的输入内容卡片 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 携带参数 |
|
||||||
|
|--------|---------|----------|
|
||||||
|
| `record_click` (来自 `Cols`) | 用户点击模型记录行时触发 | 包含所选模型信息的 `event.params` |
|
||||||
|
| `submit` (来自 `Form`) | 输入或 KDB 表单提交时触发 | `event.params` 为表单数据对象 |
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"widgettype": "LlmIO",
|
||||||
|
"id": "llm_container",
|
||||||
|
"options": {
|
||||||
|
"user_icon": "/static/imgs/user-avatar.svg",
|
||||||
|
"tts_url": "/api/tts/stream",
|
||||||
|
"estimate_url": "/api/feedback/submit",
|
||||||
|
"get_kdb_url": "/api/kdb/list",
|
||||||
|
"list_models_url": "/api/models/search",
|
||||||
|
"enabled_kdb": true,
|
||||||
|
"input_fields": [
|
||||||
|
{
|
||||||
|
"name": "prompt",
|
||||||
|
"label": "请输入问题",
|
||||||
|
"uitype": "textarea",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "session_id",
|
||||||
|
"label": "会话ID",
|
||||||
|
"uitype": "text",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"models": [
|
||||||
|
{
|
||||||
|
"llmid": "gpt-4o-mini",
|
||||||
|
"modelname": "GPT-4o Mini",
|
||||||
|
"model": "gpt-4o-mini",
|
||||||
|
"icon": "/static/imgs/gpt.svg",
|
||||||
|
"url": "/api/llm/chat/stream",
|
||||||
|
"response_mode": "stream",
|
||||||
|
"input_from": "prompt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 **注释说明:**
|
||||||
|
>
|
||||||
|
> - `widgettype`: 必须是已注册的控件名,此处为 `LlmIO`
|
||||||
|
> - `id`: 唯一标识该组件实例,便于事件绑定与查找
|
||||||
|
> - `options`:
|
||||||
|
> - `user_icon`: 用户头像图标路径
|
||||||
|
> - `tts_url`: 文转语音服务接口地址(启用语音功能)
|
||||||
|
> - `estimate_url`: 用户反馈评分提交地址(点赞/点踩)
|
||||||
|
> - `get_kdb_url`: 获取知识库列表的 API 地址
|
||||||
|
> - `list_models_url`: 模型搜索接口,返回可添加的模型列表
|
||||||
|
> - `enabled_kdb`: 是否启用知识库增强功能
|
||||||
|
> - `input_fields`: 定义输入表单字段结构,使用 `Form` 控件渲染
|
||||||
|
> - `models`: 初始加载的语言模型数组,每个对象对应一个 `LlmModel`
|
||||||
|
> - `subwidgets`: 虽然是容器控件,但内部布局由 JS 构建,通常留空
|
||||||
|
> - `binds`: 此控件自身不直接绑定外部事件,事件由子控件(如按钮)触发
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ✅ 使用场景说明
|
||||||
|
|
||||||
|
该控件适合构建如下界面:
|
||||||
|
- 支持多模型对比回答的 AI 助手前端
|
||||||
|
- 可扩展模型的知识问答系统
|
||||||
|
- 集成 TTS 语音播报和用户反馈机制
|
||||||
|
- 支持外接知识库检索与提示工程优化
|
||||||
|
|
||||||
|
通过远程 `urlwidget` 加载此 JSON 即可动态嵌入页面:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "/ui/components/llmio.ui"
|
||||||
|
},
|
||||||
|
"target": "main_content"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> ⚙️ 提示:若需启用语音朗读,确保服务器提供 `/api/tts/stream` 流式音频接口;若使用反馈功能,请实现 `estimate_url` 接口接收 `logid` 和 `value`(1=满意,-1=不满意)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
如需继续编写其他控件(如 `ModelOutput`, `LlmModel`, `LlmMsgAudio`)的文档,请告知,我可以按相同格式逐个生成。
|
||||||
88
docs/ai/llmout.md
Normal file
88
docs/ai/llmout.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# LlmOut
|
||||||
|
|
||||||
|
LlmOut 是一个用于展示大模型输出内容的容器控件,能够根据返回的数据动态渲染文本、音频、视频、图片及错误信息。类型为**容器控件**,继承自 `bricks.VBox`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`update(data)`**
|
||||||
|
更新控件显示内容。接收一个包含大模型响应数据的对象,支持以下字段:
|
||||||
|
- `content`: 主要应答文本(Markdown 格式)
|
||||||
|
- `reasoning_content`: 推理过程文本
|
||||||
|
- `error`: 错误信息
|
||||||
|
- `audio`: 音频资源 URL 或 Base64 编码字符串
|
||||||
|
- `video`: 视频资源 URL 或 Base64 编码字符串
|
||||||
|
- `image`: 单个图像 URL 或图像 URL 数组
|
||||||
|
|
||||||
|
控件会自动创建对应的子控件(如 `AudioPlayer`、`VideoPlayer`、`Image`、`MdWidget` 等)并添加到内部布局中。
|
||||||
|
|
||||||
|
- **`clear_widgets()`**
|
||||||
|
清除当前所有子控件(来自父类 `VBox`),在每次更新前调用以确保界面刷新。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件。但可通过 Bricks 的事件系统监听其子控件触发的事件(例如音频播放完成、视频加载失败等)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "llm_output_area",
|
||||||
|
"widgettype": "LlmOut",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"css": "llm-response-container"
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "submit_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "llm_output_area",
|
||||||
|
"dispatch_event": "loading:start",
|
||||||
|
"params": {
|
||||||
|
"message": "正在请求大模型响应..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "submit_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "llm_output_area",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/llm/response",
|
||||||
|
"method": "POST",
|
||||||
|
"params": {
|
||||||
|
"prompt": "data:text_input.getValue()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "确认提交",
|
||||||
|
"message": "您确定要发送此请求吗?",
|
||||||
|
"confirmText": "确定",
|
||||||
|
"cancelText": "取消"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `widgettype: "LlmOut"` 表示使用已注册的 LlmOut 控件。
|
||||||
|
> - `options.width`: 设置控件宽度占满父容器。
|
||||||
|
> - `binds` 中定义了两个行为:
|
||||||
|
> 1. 当按钮 `submit_btn` 被点击时,向 `llm_output_area` 派发 `loading:start` 自定义事件,可用于显示加载状态。
|
||||||
|
> 2. 同时发起一个远程请求获取新的 LLM 响应,并将结果替换当前 `LlmOutputArea` 的内容。
|
||||||
|
> - `data:text_input.getValue()` 是运行时数据绑定语法,表示从 ID 为 `text_input` 的控件中获取用户输入作为请求参数。
|
||||||
|
> - 使用 `conform` 提供用户确认弹窗,防止误操作。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
该控件适用于 AI 对话系统、智能助手界面等需要动态展示多模态输出的场景。
|
||||||
140
docs/ai/markdown_viewer.md
Normal file
140
docs/ai/markdown_viewer.md
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
# MarkdownViewer
|
||||||
|
|
||||||
|
用于展示 Markdown 格式内容的容器控件,支持从本地文本或远程 URL 加载 Markdown 内容,并具备浏览历史回退功能。该控件继承自 `VBox`,属于**容器控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `build()`
|
||||||
|
异步方法,用于初始化加载由 `opts.md_url` 指定的 Markdown 内容。
|
||||||
|
|
||||||
|
- `_build(md_url)`
|
||||||
|
异步私有方法,根据传入的 URL 请求并渲染 Markdown 内容到界面中。
|
||||||
|
|
||||||
|
- `createBackButton()`
|
||||||
|
创建一个返回按钮(“<<<<<<<”),点击后可返回上一个浏览过的 Markdown 页面。
|
||||||
|
|
||||||
|
- `add_back_stack(event)`
|
||||||
|
将当前页面的 URL 压入浏览历史栈(`back_stack`)中,用于实现“后退”功能。
|
||||||
|
|
||||||
|
- `go_back(event)`
|
||||||
|
异步方法,弹出当前和上一个 URL,然后加载再上一级的内容,实现浏览器式的“返回”操作。
|
||||||
|
|
||||||
|
- `show_scroll(event)`
|
||||||
|
滚动事件监听函数,调试用,输出当前窗口滚动位置。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `'loaded'`
|
||||||
|
当 Markdown 内容成功加载并解析完成后触发,携带参数 `{ url: 当前加载的URL }`。
|
||||||
|
|
||||||
|
- `'scroll'`
|
||||||
|
监听容器滚动行为,触发 `show_scroll` 函数进行调试输出。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "md_viewer_1",
|
||||||
|
"widgettype": "MarkdownViewer",
|
||||||
|
"options": {
|
||||||
|
"navigator": true, // 显示返回按钮
|
||||||
|
"md_url": "/docs/intro.md", // 从服务器加载 Markdown 文件
|
||||||
|
"method": "GET", // HTTP 方法
|
||||||
|
"params": {} // 请求参数(无)
|
||||||
|
},
|
||||||
|
"subwidgets": [], // 此控件内部管理子控件,无需手动定义
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "md_viewer_1",
|
||||||
|
"event": "loaded",
|
||||||
|
"target": "Popup",
|
||||||
|
"rtdata": {
|
||||||
|
"msg": "文档已加载完成!"
|
||||||
|
},
|
||||||
|
"actiontype": "script",
|
||||||
|
"script": "console.log('Markdown loaded:', params.url);",
|
||||||
|
"params": {
|
||||||
|
"url": "{event.params.url}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 使用 `MarkdownViewer` 控件时,只需提供 `md_url` 或 `mdtext` 即可自动渲染 Markdown。
|
||||||
|
> - 若启用 `navigator: true`,则会显示一个简单的返回按钮,支持浏览历史回退。
|
||||||
|
> - `binds` 中监听了 `loaded` 事件,在内容加载完成后执行脚本打印日志。
|
||||||
|
> - 支持 Markdown 中的链接跳转,点击链接会动态加载新页面并记录历史。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# MdWidget
|
||||||
|
|
||||||
|
基础 Markdown 渲染控件,用于将 Markdown 文本转换为 HTML 并显示在页面上。它是一个普通控件,继承自 `JsWidget`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `set_content(content)`
|
||||||
|
设置新的 Markdown 内容并重新渲染。
|
||||||
|
|
||||||
|
- `_build(md_url)`
|
||||||
|
异步方法,通过 AJAX 获取指定 URL 的 Markdown 内容并渲染。
|
||||||
|
|
||||||
|
- `_build1()`
|
||||||
|
使用 `marked.parse()` 将 `this.md_content` 转换为 HTML 并插入 DOM。
|
||||||
|
|
||||||
|
- `getValue()`
|
||||||
|
返回当前控件的数据对象,格式为 `{ 控件名: markdown内容 }`,用于表单提交等场景。
|
||||||
|
|
||||||
|
- `setValue(v)`
|
||||||
|
设置 Markdown 内容值(可用于动态更新内容)。
|
||||||
|
|
||||||
|
- `getname()`
|
||||||
|
获取控件名称,若未设置则默认为 `'mdtext'`。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `'loaded'`
|
||||||
|
成功加载远程 Markdown 文件后触发,携带参数 `{ url: 加载的文件地址 }`。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "md_widget_simple",
|
||||||
|
"widgettype": "MdWidget",
|
||||||
|
"options": {
|
||||||
|
"mdtext": "# 欢迎使用 Bricks\\n\\n这是一个内联 Markdown 示例。\\n\\n- 功能一\\n- 功能二"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "md_widget_simple",
|
||||||
|
"event": "click",
|
||||||
|
"target": "md_widget_simple",
|
||||||
|
"dispatch_event": "content_clicked",
|
||||||
|
"params": {
|
||||||
|
"info": "用户点击了 Markdown 区域"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 此例使用内联字符串 `mdtext` 直接嵌入 Markdown 内容。
|
||||||
|
> - 绑定了 `click` 事件,当用户点击渲染后的 Markdown 区域时,派发自定义事件 `content_clicked`。
|
||||||
|
> - 可与其它控件通信,例如通知父组件用户交互行为。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 💡 **提示:**
|
||||||
|
> 使用这两个控件前,请确保已引入 `marked.js`:
|
||||||
|
>
|
||||||
|
> ```html
|
||||||
|
> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> 否则 `marked.parse is not a function` 错误将导致渲染失败。
|
||||||
136
docs/ai/menu.md
Normal file
136
docs/ai/menu.md
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# Menu
|
||||||
|
|
||||||
|
**用途**:`Menu` 是一个用于构建树形结构菜单的容器控件,支持多级子菜单、动态加载子菜单内容(通过 URL 异步加载)、点击触发页面跳转或弹窗等功能。常用于侧边栏导航、系统功能入口等场景。
|
||||||
|
|
||||||
|
**类型**:容器控件,继承自 `bricks.VBox`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `create_menuitem(item)`
|
||||||
|
根据菜单项配置创建一个 HBox 形式的菜单项,包含图标和文本,并绑定数据。
|
||||||
|
|
||||||
|
- `create_submenu_container()`
|
||||||
|
创建一个用于包裹子菜单的 VBox 容器,默认隐藏(`display: none`),并设置左外边距以实现缩进效果。
|
||||||
|
|
||||||
|
- `create_children(w, items)`
|
||||||
|
递归创建菜单项及其子菜单。支持静态嵌套菜单(`items`)和动态加载菜单(`submenu` 属性指定 URL)。
|
||||||
|
|
||||||
|
- `menu_clicked(event)`
|
||||||
|
菜单项被点击时的回调函数。根据目标类型(如 `PopupWindow`、`Popup` 或普通控件)加载远程 UI 并渲染到目标容器中,同时派发 `command` 事件。
|
||||||
|
|
||||||
|
- `load_submenu(container, event)`
|
||||||
|
动态加载子菜单内容(通过 `submenu_url` 指定的 URL 获取 JSON 数据),仅在首次展开时加载一次,提升性能。
|
||||||
|
|
||||||
|
- `items_toggle_hide(w, event)`
|
||||||
|
切换子菜单的显示/隐藏状态,阻止事件冒泡。
|
||||||
|
|
||||||
|
- `regen_menuitem_event(item, event)`
|
||||||
|
当普通菜单项被点击时,重新派发 `item_click` 事件,携带该菜单项的数据。
|
||||||
|
|
||||||
|
- `get_submenu_items(url)`
|
||||||
|
异步从服务器获取子菜单数据(返回 JSON 中的 `items` 数组),用于动态加载。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `item_click`
|
||||||
|
当任意菜单项被点击时触发,参数为当前菜单项的配置对象(如 `label`, `url`, `target` 等)。通常由 `regen_menuitem_event` 触发。
|
||||||
|
|
||||||
|
- `command`
|
||||||
|
在 `menu_clicked` 方法中派发,表示已执行某个命令(例如跳转、打开弹窗等),携带原始菜单项参数,可用于外部监听处理业务逻辑。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "main_menu",
|
||||||
|
"widgettype": "Menu",
|
||||||
|
"options": {
|
||||||
|
"bgcolor": "#f5f5f5",
|
||||||
|
"item_cheight": 2.5,
|
||||||
|
"menuitem_css": "custom-menu-item"
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "main_menu",
|
||||||
|
"event": "command",
|
||||||
|
"target": "status_bar",
|
||||||
|
"datawidget": "main_menu",
|
||||||
|
"datamethod": "getValue",
|
||||||
|
"rtdata": {
|
||||||
|
"message": "菜单命令已执行"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"label": "仪表盘",
|
||||||
|
"icon": "/icons/dashboard.png",
|
||||||
|
"url": "/ui/dashboard.ui",
|
||||||
|
"target": "content_area"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "用户管理",
|
||||||
|
"icon": "/icons/users.png",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"label": "用户列表",
|
||||||
|
"url": "/ui/user/list.ui",
|
||||||
|
"target": "content_area"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "角色权限",
|
||||||
|
"url": "/ui/user/roles.ui",
|
||||||
|
"target": "Popup"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "报表中心",
|
||||||
|
"icon": "/icons/reports.png",
|
||||||
|
"submenu": "/api/menu/reports", // 动态加载子菜单
|
||||||
|
"target": "content_area"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "系统设置",
|
||||||
|
"icon": "/icons/settings.png",
|
||||||
|
"url": "/ui/settings.ui",
|
||||||
|
"target": "PopupWindow",
|
||||||
|
"popup_options": {
|
||||||
|
"width": 800,
|
||||||
|
"height": 600,
|
||||||
|
"title": "系统设置"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释说明:
|
||||||
|
|
||||||
|
- `"widgettype": "Menu"`:使用注册的 `Menu` 控件。
|
||||||
|
- `options.items`:定义菜单结构数组,每个元素是一个菜单项。
|
||||||
|
- `label`:显示文本,支持 i18n。
|
||||||
|
- `icon`:左侧图标路径。
|
||||||
|
- `url`:点击后要加载的 `.ui` 文件地址。
|
||||||
|
- `target`:目标容器 ID 或特殊值:
|
||||||
|
- `"content_area"`:普通容器控件 ID。
|
||||||
|
- `"Popup"`:在浮层中打开。
|
||||||
|
- `"PopupWindow"`:在新窗口中打开。
|
||||||
|
- `items`:静态嵌套子菜单。
|
||||||
|
- `submenu`:字符串 URL,表示此菜单项的子菜单需异步加载(首次点击展开时请求)。
|
||||||
|
- `binds` 示例:监听 `command` 事件,在状态栏提示操作成功。
|
||||||
|
- `options.bgcolor`:设置菜单背景色。
|
||||||
|
- `item_cheight`:控制菜单项高度。
|
||||||
|
- `menuitem_css`:自定义菜单项样式类名。
|
||||||
|
|
||||||
|
> 💡 **提示**:若某菜单项有 `submenu` 字段,则其子菜单将在第一次展开时通过 AJAX 请求获取,适用于大型系统中按需加载菜单结构,减少初始资源消耗。
|
||||||
116
docs/ai/message.md
Normal file
116
docs/ai/message.md
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# Message
|
||||||
|
|
||||||
|
用于在页面中弹出一个包含文本消息的对话框,常用于提示用户信息。类型为**容器控件**,继承自 `PopupWindow` 控件。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **constructor(opts)**
|
||||||
|
构造函数,接收配置项 `opts` 并初始化弹窗。自动设置 `auto_open = true`,创建完成后立即打开弹窗。
|
||||||
|
|
||||||
|
- **create_message_widget()**
|
||||||
|
创建内部显示结构:使用 `Filler` 布局填充 → 添加垂直滚动面板 `VScrollPanel` → 插入可换行、居中文本控件 `Text` 显示消息内容。
|
||||||
|
|
||||||
|
- **set_css(cssClass)**
|
||||||
|
设置弹窗整体的 CSS 类名(如 `'message'` 或 `'error'`),用于样式定制。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件。依赖父类 `PopupWindow` 提供的窗口生命周期事件(如 `onOpen`, `onClose`)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "msg_info",
|
||||||
|
"widgettype": "Message",
|
||||||
|
"options": {
|
||||||
|
"title": "系统提示", // 弹窗标题
|
||||||
|
"message": "操作已成功提交!", // 要显示的消息文本
|
||||||
|
"cheight": 9, // 内容高度(单位:rem)
|
||||||
|
"cwidth": 16, // 内容宽度(单位:rem)
|
||||||
|
"i18n": true // 支持国际化文本
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ 注释说明:
|
||||||
|
> - `widgettype` 为 `"Message"`,表示使用注册的 `Message` 类。
|
||||||
|
> - `options.message` 是核心字段,用于传入要展示的文本。
|
||||||
|
> - `cheight` 和 `cwidth` 控制弹窗尺寸,默认值由 `bricks.show_message` 函数提供。
|
||||||
|
> - 实际开发中通常不直接写此 JSON,而是调用封装函数 `bricks.show_message()`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Error
|
||||||
|
|
||||||
|
用于弹出错误提示信息,视觉上与 `Message` 不同(通常是红色主题)。类型为**容器控件**,继承自 `Message`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **constructor(opts)**
|
||||||
|
继承父类 `Message` 的构造逻辑,并调用 `set_css('error')` 更改外观为主题色“错误红”。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无额外事件,沿用 `Message` 及其父类事件体系。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "err_network",
|
||||||
|
"widgettype": "Error",
|
||||||
|
"options": {
|
||||||
|
"title": "网络错误",
|
||||||
|
"message": "无法连接到服务器,请检查网络设置。",
|
||||||
|
"cheight": 10,
|
||||||
|
"cwidth": 20,
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ 注释说明:
|
||||||
|
> - 使用 `widgettype: "Error"` 即可快速生成带错误样式的弹窗。
|
||||||
|
> - 外观差异通过 `set_css('error')` 实现,开发者无需重复构建 UI 结构。
|
||||||
|
> - 推荐使用封装函数 `bricks.show_error(opts)` 替代手动编写 JSON。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# bricks.show_message / bricks.show_error(辅助函数)
|
||||||
|
|
||||||
|
虽然不是控件本身,但这两个全局函数是实际项目中最常用的接口。
|
||||||
|
|
||||||
|
## 示例:调用封装函数(推荐方式)
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 显示普通消息
|
||||||
|
bricks.show_message({
|
||||||
|
title: "欢迎",
|
||||||
|
message: "您好,欢迎使用 Bricks.js 框架!",
|
||||||
|
cheight: 8,
|
||||||
|
cwidth: 15
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示错误消息
|
||||||
|
bricks.show_error({
|
||||||
|
title: "保存失败",
|
||||||
|
message: "数据校验未通过,请检查输入字段。",
|
||||||
|
cwidth: 20
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 提示:这些函数会自动补全默认宽高,并实例化对应的 `Message` 或 `Error` 控件并调用 `.open()` 方法显示弹窗。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
🔚 总结:
|
||||||
|
`Message` 和 `Error` 都是基于 `PopupWindow` 的语义化弹窗控件,适用于轻量级信息反馈场景。通过 JSON 可以完全控制其行为,但更建议使用 `bricks.show_message()` 和 `bricks.show_error()` 快捷方法提高开发效率。
|
||||||
122
docs/ai/miniform.md
Normal file
122
docs/ai/miniform.md
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
# MiniForm
|
||||||
|
|
||||||
|
MiniForm 是一个轻量级表单控件,用于在水平布局中动态切换输入字段。它继承自 `HBox`,属于**容器控件**,允许用户从多个预定义字段中选择一个进行输入,并实时触发值变化事件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`build()`**
|
||||||
|
初始化控件结构,调用 `build_options` 和 `build_widgets` 构建下拉选择与输入区域。
|
||||||
|
|
||||||
|
- **`build_options()`**
|
||||||
|
创建一个下拉选择控件(基于 Input 的 code 类型),用于展示所有可选字段的标签列表,支持通过 `valueField` 和 `textField` 配置数据映射。
|
||||||
|
|
||||||
|
- **`build_widgets(name)`**
|
||||||
|
根据传入的字段名 `name` 动态创建对应的输入控件(如文本框、数字框等),并替换当前输入区域的内容。
|
||||||
|
|
||||||
|
- **`change_input(e)`**
|
||||||
|
下拉选择改变时的回调函数,获取新选中的字段名称并重新构建输入控件。
|
||||||
|
|
||||||
|
- **`input_handle(e)`**
|
||||||
|
输入内容发生变化时触发,合并当前输入值到参数对象中,并派发 `input` 事件通知外部。
|
||||||
|
|
||||||
|
- **`getValue()`**
|
||||||
|
获取当前完整的表单数据:包括预设的 `params` 和当前输入控件的值。
|
||||||
|
|
||||||
|
- **`show_options(e)`**
|
||||||
|
调试用方法,手动显示下拉选项(实际由 Input 控件自动管理)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`input`**
|
||||||
|
当输入值发生变更时触发,携带合并后的数据对象作为参数。可用于绑定上级组件的数据更新或验证逻辑。
|
||||||
|
|
||||||
|
- **`changed`(内部绑定)**
|
||||||
|
绑定在下拉选择控件上,当用户切换字段类型时触发,驱动界面重新渲染对应输入控件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "mini_form_example",
|
||||||
|
"widgettype": "MiniForm",
|
||||||
|
"options": {
|
||||||
|
"defaultname": "username", // 默认选中的字段名
|
||||||
|
"label_width": "80px", // 字段标签宽度(若适用)
|
||||||
|
"input_width": "200px", // 输入框宽度
|
||||||
|
"params": { // 额外附加的静态参数
|
||||||
|
"formId": "user_create"
|
||||||
|
},
|
||||||
|
"fields": [ // 可选字段配置数组
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"label": "用户名",
|
||||||
|
"icon": "user",
|
||||||
|
"uitype": "text", // 使用文本输入框
|
||||||
|
"uiparams": {
|
||||||
|
"placeholder": "请输入用户名"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "age",
|
||||||
|
"label": "年龄",
|
||||||
|
"icon": "number",
|
||||||
|
"uitype": "number", // 使用数字输入框
|
||||||
|
"uiparams": {
|
||||||
|
"min": 1,
|
||||||
|
"max": 120
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"label": "邮箱",
|
||||||
|
"icon": "envelope",
|
||||||
|
"uitype": "text",
|
||||||
|
"uiparams": {
|
||||||
|
"type": "email",
|
||||||
|
"placeholder": "请输入邮箱地址"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "mini_form_example",
|
||||||
|
"event": "input",
|
||||||
|
"target": "data_collector",
|
||||||
|
"dispatch_event": "form_value_updated",
|
||||||
|
"params": {
|
||||||
|
"source": "mini_form"
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"timestamp": "${now}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "mini_form_example",
|
||||||
|
"event": "input",
|
||||||
|
"target": "",
|
||||||
|
"script": "console.log('当前表单值:', data);",
|
||||||
|
"params": {
|
||||||
|
"data": "${@wid.getValue()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subwidgets": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `fields` 中每个字段定义了唯一 `name`、显示 `label`、图标 `icon` 以及具体的 UI 类型和参数。
|
||||||
|
> - `defaultname` 设置默认激活的字段;若未设置,则使用第一个字段。
|
||||||
|
> - `binds` 示例展示了如何监听 `input` 事件:
|
||||||
|
> - 第一条:将数据转发给 ID 为 `data_collector` 的控件,触发自定义事件 `form_value_updated`,并附带时间戳。
|
||||||
|
> - 第二条:执行脚本输出当前值到控制台,`${@wid.getValue()}` 表示调用该控件的 `getValue()` 方法获取运行时数据。
|
||||||
|
> - `subwidgets` 为空,因为 MiniForm 自行管理子控件(通过 add_widget),不依赖 JSON 子节点描述。
|
||||||
123
docs/ai/modal.md
Normal file
123
docs/ai/modal.md
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
# Modal
|
||||||
|
|
||||||
|
Modal 是一个模态窗口控件,用于在当前页面上层显示一个浮动的对话框。它继承自 `BaseModal`,属于**容器控件**,可以包含其他子控件(如表单、文本、按钮等),常用于提示信息、确认操作或展示临时内容。
|
||||||
|
|
||||||
|
类型:容器控件,继承自 `bricks.BaseModal`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **open()**
|
||||||
|
显示模态框,设置其 `display` 样式为可见,并触发 `opened` 事件。如果设置了超时时间(`timeout`),会启动定时关闭任务。
|
||||||
|
|
||||||
|
- **dismiss()**
|
||||||
|
隐藏并移除模态框,取消可能存在的超时任务,并派发 `dismissed` 事件。
|
||||||
|
|
||||||
|
- **add_widget(w, index)**
|
||||||
|
向模态框的内容区域添加子控件。若配置了 `auto_open: true`,则自动调用 `open()` 方法打开模态框。
|
||||||
|
|
||||||
|
- **get_zindex()**
|
||||||
|
获取当前模态框应使用的 `z-index` 值,确保新弹出的模态框始终位于最上层。
|
||||||
|
|
||||||
|
- **create_title()**
|
||||||
|
创建标题栏,包括标题文字和右上角关闭图标(SVG 图标),支持国际化(i18n)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **opened**
|
||||||
|
当模态框被成功打开时触发。
|
||||||
|
|
||||||
|
- **dismissed**
|
||||||
|
当模态框被关闭并从 DOM 中移除后触发。
|
||||||
|
|
||||||
|
- **click (内部处理)**
|
||||||
|
点击遮罩背景区域可关闭模态框(仅当 `auto_close` 为 `true` 时启用)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "example_modal",
|
||||||
|
"widgettype": "Modal",
|
||||||
|
"options": {
|
||||||
|
"title": "操作确认", // 模态框标题,支持 i18n 自动翻译
|
||||||
|
"width": "400px", // 宽度
|
||||||
|
"height": "200px", // 高度
|
||||||
|
"bgcolor": "#ffffff", // 内容面板背景色
|
||||||
|
"archor": "cc", // 居中对齐(center-center)
|
||||||
|
"auto_open": false, // 不自动打开,需手动触发
|
||||||
|
"timeout": 0 // 无自动关闭时间
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "confirm_text",
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"otext": "您确定要执行此操作吗?",
|
||||||
|
"i18n": true,
|
||||||
|
"style": { "padding": "20px", "textAlign": "center" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "button_row",
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": { "justify": "end", "padding": "10px" },
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "cancel_btn",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": { "text": "取消", "i18n": true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "confirm_btn",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": { "text": "确定", "i18n": true, "variant": "primary" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "cancel_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "example_modal",
|
||||||
|
"method": "dismiss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "confirm_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "example_modal",
|
||||||
|
"dispatch_event": "submit",
|
||||||
|
"params": { "action": "delete_item" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "example_modal",
|
||||||
|
"event": "dismissed",
|
||||||
|
"target": "logger",
|
||||||
|
"dispatch_event": "log",
|
||||||
|
"params": { "msg": "Modal closed by user." }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
>
|
||||||
|
> - 使用 `Modal` 控件创建一个居中的对话框。
|
||||||
|
> - 包含一段提示文本和两个按钮(取消/确定)。
|
||||||
|
> - 点击“取消”调用 `dismiss()` 关闭模态框。
|
||||||
|
> - 点击“确定”派发一个名为 `submit` 的自定义事件,携带操作参数。
|
||||||
|
> - 模态框关闭后,向日志组件发送一条日志消息。
|
||||||
|
> - 所有文本均支持国际化(`i18n: true`),可通过语言包动态切换语言。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
💡 提示:可通过 JavaScript 动态创建或通过 `.ui` 文件以 JSON 形式声明使用。结合 `urlwidget` 可实现远程加载模态内容,提升模块化能力。
|
||||||
67
docs/ai/multiple_state_image.md
Normal file
67
docs/ai/multiple_state_image.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# MultipleStateImage
|
||||||
|
|
||||||
|
用于展示一个具有多个状态的图片控件,点击图片时可在不同状态间循环切换。该控件属于**普通控件**,继承自 `bricks.Layout`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`set_state(state)`**
|
||||||
|
切换到指定的状态(state),并更新显示的图片。
|
||||||
|
参数:
|
||||||
|
- `state` (String) — 目标状态名称,必须是 `urls` 配置中存在的键。
|
||||||
|
|
||||||
|
- **`change_state(event)`**
|
||||||
|
内部方法,响应图片的点击事件,自动切换到下一个状态,支持循环切换。触发 `state_changed` 自定义事件。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`state_changed`**
|
||||||
|
当图片状态发生改变时触发。
|
||||||
|
携带数据:当前状态名(String)。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "msi_example", // 控件唯一标识
|
||||||
|
"widgettype": "MultipleStateImage", // 控件类型,必须为已注册的控件名
|
||||||
|
"options": {
|
||||||
|
"state": "normal", // 初始化状态
|
||||||
|
"urls": { // 各状态对应的图片URL
|
||||||
|
"normal": "/images/button_normal.png",
|
||||||
|
"hover": "/images/button_hover.png",
|
||||||
|
"pressed": "/images/button_pressed.png"
|
||||||
|
},
|
||||||
|
"width": 100, // 图片宽度
|
||||||
|
"height": 80 // 图片高度
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event", // 绑定一个自定义事件派发
|
||||||
|
"wid": "msi_example", // 触发组件ID
|
||||||
|
"event": "click", // 监听点击事件
|
||||||
|
"target": "some_other_widget", // 目标控件ID
|
||||||
|
"dispatch_event": "image_clicked", // 派发事件名称
|
||||||
|
"params": {
|
||||||
|
"source": "MultipleStateImage" // 传递额外参数
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script", // 执行脚本,记录当前状态
|
||||||
|
"wid": "msi_example",
|
||||||
|
"event": "state_changed", // 监听状态变化事件
|
||||||
|
"target": "ConsoleLogger",
|
||||||
|
"script": "console.log('Image state changed to:', data);",
|
||||||
|
"params": {
|
||||||
|
"data": "{event_data}" // 使用运行时事件数据
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 **说明与注释:**
|
||||||
|
> - `MultipleStateImage` 将一组图片 URL 映射到不同的“状态”,通过调用 `set_state()` 或点击实现切换。
|
||||||
|
> - 每次状态变更会触发 `state_changed` 事件,可用于联动其他控件或日志记录。
|
||||||
|
> - 此控件利用了 `bricks.Image` 作为内部子控件进行渲染,并封装其行为。
|
||||||
|
> - 在 JSON 中使用时,需确保所有状态在 `urls` 对象中都有对应图片地址。
|
||||||
|
> - 支持通过 `binds` 绑定交互逻辑,例如点击后通知其他模块或执行脚本。
|
||||||
78
docs/ai/period.md
Normal file
78
docs/ai/period.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# PeriodDays
|
||||||
|
|
||||||
|
该控件用于展示一个可点击的日期区间(起始日期至结束日期),用户可以通过点击日期实现向前或向后翻动时间段。适用于报表周期选择、日志查看等需要动态切换时间范围的场景。
|
||||||
|
**类型**:普通控件(但内部组合多个子控件);继承自 `bricks.HBox`,属于布局容器的一种使用形式,但从功能上归类为**普通复合控件**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `date_add(strdate, step_cnt, step_type)`
|
||||||
|
根据指定的步长和单位(天/月/年)对输入的日期字符串进行增减,并返回格式化后的日期字符串。
|
||||||
|
|
||||||
|
- `step_back()`
|
||||||
|
将当前起始和结束日期同时向前移动一个步长时间段,并触发 `changed` 事件。
|
||||||
|
|
||||||
|
- `step_forward()`
|
||||||
|
将当前起始和结束日期同时向后移动一个步长时间段,并触发 `changed` 事件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `changed`
|
||||||
|
当用户点击起始或结束日期导致时间区间变化时触发,携带新的 `{ start_date, end_date }` 数据对象。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "period_selector",
|
||||||
|
"widgettype": "PeriodDays",
|
||||||
|
"options": {
|
||||||
|
"start_date": "2024-01-01", // 初始开始日期
|
||||||
|
"end_date": "2024-01-31", // 初始结束日期
|
||||||
|
"step_type": "months", // 步进类型:支持 'days', 'months', 'years'
|
||||||
|
"step_cnt": 1, // 每次翻动的步数(如每月前进/后退)
|
||||||
|
"title": "统计周期", // 可选标题,显示在日期前
|
||||||
|
"splitter": " 至 ", // 分隔符,默认是中文“至”,支持国际化
|
||||||
|
"i18n": true // 启用国际化支持
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "period_selector",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "data_report_panel",
|
||||||
|
"dispatch_event": "refresh",
|
||||||
|
"params": {
|
||||||
|
"source": "period_selector"
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"msg": "日期已更新"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "period_selector",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "ConsoleLogger",
|
||||||
|
"script": "console.log('Period changed:', params.start_date, 'to', params.end_date);",
|
||||||
|
"params": {
|
||||||
|
"start_date": "{%event_data.start_date%}",
|
||||||
|
"end_date": "{%event_data.end_date%}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 此控件通过两个可点击的文本标签(`Text`)来显示起止日期。
|
||||||
|
> - 点击任意一个日期会触发前移或后移操作,自动计算新时间段并更新界面。
|
||||||
|
> - 使用了 `bricks.str2date` 和 `bricks.date2str` 工具函数处理日期格式转换。
|
||||||
|
> - 支持与其它控件通信,例如通过 `binds` 中的 `event` 动作通知数据面板刷新内容。
|
||||||
|
> - `script` 类型绑定可用于调试或执行自定义逻辑。
|
||||||
|
> - 所有文本均支持 i18n 国际化替换,适合多语言环境。
|
||||||
100
docs/ai/pie.md
Normal file
100
docs/ai/pie.md
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# ChartPie
|
||||||
|
|
||||||
|
ChartPie 是一个基于 ECharts 的饼图控件,用于可视化展示分类数据的占比情况。属于**普通控件**,继承自 `EchartsExt` 控件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`setup_options(data)`**
|
||||||
|
根据传入的数据 `data` 和控件配置项(如 `nameField`, `valueFields` 等)生成符合 ECharts 饼图格式的图表选项对象(options),供底层 ECharts 渲染使用。
|
||||||
|
|
||||||
|
- **`render()`**
|
||||||
|
(继承自 `EchartsExt`)调用 `setup_options` 生成配置,并初始化或更新 ECharts 实例进行图表渲染。
|
||||||
|
|
||||||
|
- **`loadData()`**
|
||||||
|
(继承自 `JsWidget` 基类)从 `data_url` 指定的接口加载数据,成功后触发 `render` 方法重新绘制图表。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`element_click`**
|
||||||
|
当用户点击饼图中的某个扇形区域时触发,携带被点击项的数据信息(如 `name`, `value`)作为事件参数,可用于联动其他组件或弹窗提示。
|
||||||
|
|
||||||
|
> 示例:点击某分类扇形后,通过事件绑定刷新表格内容,显示该分类的详细数据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "chart_pie_sales",
|
||||||
|
"widgettype": "ChartPie",
|
||||||
|
"options": {
|
||||||
|
"title": "销售类别占比", // 图表标题
|
||||||
|
"description": "各产品类别的销售额分布", // 描述信息(可选)
|
||||||
|
"legend": { // 图例配置
|
||||||
|
"orient": "vertical",
|
||||||
|
"left": "right"
|
||||||
|
},
|
||||||
|
"nameField": "category", // 数据中表示名称的字段
|
||||||
|
"valueFields": ["sales"], // 数据中表示值的字段数组(饼图只支持一个)
|
||||||
|
"pie_options": { // 自定义饼图系列配置
|
||||||
|
"radius": "70%",
|
||||||
|
"center": ["50%", "50%"],
|
||||||
|
"label": {
|
||||||
|
"show": true,
|
||||||
|
"formatter": "{b}: {d}%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data_url": "/api/report/sales-by-category", // 获取数据的API地址
|
||||||
|
"data_params": { // 请求参数
|
||||||
|
"period": "Q3"
|
||||||
|
},
|
||||||
|
"width": "600px",
|
||||||
|
"height": "400px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "chart_pie_sales",
|
||||||
|
"event": "element_click",
|
||||||
|
"target": "table_detail_panel",
|
||||||
|
"dispatch_event": "refresh_data",
|
||||||
|
"params": {
|
||||||
|
"source": "chart_pie_sales"
|
||||||
|
},
|
||||||
|
"datawidget": "chart_pie_sales",
|
||||||
|
"datamethod": "getValue",
|
||||||
|
"dataparams": {},
|
||||||
|
"rtdata": {
|
||||||
|
"action": "filter_by_category"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "chart_pie_sales",
|
||||||
|
"event": "init",
|
||||||
|
"target": "Popup",
|
||||||
|
"options": {
|
||||||
|
"url": "/views/popup/loading.ui",
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
"mode": "replace",
|
||||||
|
"rtdata": {
|
||||||
|
"message": "正在加载饼图数据..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
>
|
||||||
|
> - 此控件在初始化时会从 `/api/report/sales-by-category?period=Q3` 加载数据;
|
||||||
|
> - 使用 `nameField` 和 `valueFields` 映射数据字段,构建饼图数据结构;
|
||||||
|
> - 用户点击某个扇区时,派发 `refresh_data` 事件给 ID 为 `table_detail_panel` 的控件,实现联动;
|
||||||
|
> - 同时绑定了 `init` 事件,在初始化阶段弹出一个加载提示窗口(通过 `Popup` 目标);
|
||||||
|
> - 支持国际化、动态参数和远程模板加载,体现 bricks 框架的模块化能力。
|
||||||
227
docs/ai/popup.md
Normal file
227
docs/ai/popup.md
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
# Popup
|
||||||
|
|
||||||
|
弹窗控件,用于在页面上显示浮动的对话框或内容窗口。属于**容器控件**,继承自 `bricks.VBox`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `open()`:打开弹窗,设置位置、显示样式,并触发 `opened` 事件。
|
||||||
|
- `dismiss()`:关闭弹窗,隐藏其 DOM 元素,并可选择自动销毁。
|
||||||
|
- `destroy()`:彻底销毁该弹窗实例,从父容器中移除并清理资源。
|
||||||
|
- `add_widget(w, i)`:向弹窗内容区域添加子控件。
|
||||||
|
- `remove_widget(w)`:从内容区域移除指定子控件。
|
||||||
|
- `clear_widgets()`:清空内容区域的所有子控件。
|
||||||
|
- `bring_to_top()`:将当前弹窗置于所有其他弹窗之上(通过提升 z-index)。
|
||||||
|
- `positify_tl()`:根据锚点(archor)和屏幕尺寸计算并设置弹窗初始位置。
|
||||||
|
- `popup_from_widget(from_w)`:相对于某个源控件定位弹窗(常用于下拉菜单等场景)。
|
||||||
|
- `load_content()`:异步加载 `content` 配置中的组件并渲染到内容区。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `opened`:弹窗打开后触发。
|
||||||
|
- `dismissed`:弹窗关闭时触发。
|
||||||
|
- `destroy`:弹窗被销毁时触发(仅当 `auto_destroy` 为 true 时)。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "my_popup",
|
||||||
|
"widgettype": "Popup",
|
||||||
|
"options": {
|
||||||
|
"width": "400px", // 弹窗宽度
|
||||||
|
"height": "300px", // 弹窗高度
|
||||||
|
"archor": "cc", // 居中显示:'cc' 表示 center-center
|
||||||
|
"modal": true, // 是否模态,模态时背景不可点击
|
||||||
|
"movable": true, // 是否允许拖动
|
||||||
|
"resizable": true, // 是否允许调整大小
|
||||||
|
"auto_open": false, // 是否创建后自动打开
|
||||||
|
"auto_dismiss": true, // 点击外部是否自动关闭
|
||||||
|
"auto_destroy": true, // 关闭后是否自动销毁
|
||||||
|
"timeout": 5000, // 自动关闭延时(毫秒),0 表示不启用
|
||||||
|
"content": { // 要加载的内容(支持嵌套控件)
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"padding": "20px",
|
||||||
|
"css": "popup-content"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "这是一个弹窗示例!",
|
||||||
|
"i18n": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"text": "关闭",
|
||||||
|
"css": "primary"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "close_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "my_popup",
|
||||||
|
"dispatch_event": "dismissed"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "trigger_button", // 触发控件 ID
|
||||||
|
"event": "click", // 监听点击事件
|
||||||
|
"target": "my_popup", // 目标是此弹窗
|
||||||
|
"method": "open", // 执行 open 方法
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "my_popup",
|
||||||
|
"event": "dismissed",
|
||||||
|
"target": "status_text",
|
||||||
|
"dispatch_event": "setValue",
|
||||||
|
"params": {
|
||||||
|
"value": "弹窗已关闭"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明**:
|
||||||
|
> - 此弹窗不会自动打开(`auto_open: false`),需由按钮触发。
|
||||||
|
> - 点击“关闭”按钮会派发 `dismissed` 事件,进而触发状态更新。
|
||||||
|
> - 使用 `content` 字段定义内部结构,支持动态构建复杂界面。
|
||||||
|
> - 支持国际化文本(`i18n: true`)、拖拽、缩放、模态遮罩等功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# PopupWindow
|
||||||
|
|
||||||
|
带标题栏的可操作窗口型弹窗控件,适用于桌面风格的应用程序窗口管理。属于**容器控件**,继承自 `bricks.Popup`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `open()`:打开窗口,若设置了自动打开则延迟执行。
|
||||||
|
- `build_title_bar()`:构建顶部标题栏(含图标、工具按钮等)。
|
||||||
|
- `win_minimize()`:最小化窗口(实际是关闭但保留引用供恢复)。
|
||||||
|
- `set_title(txt)`:动态设置窗口标题。
|
||||||
|
- `destroy()`:销毁窗口,同时从全局管理列表中移除。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `opened`:窗口打开时触发。
|
||||||
|
- `dismissed`:窗口关闭(最小化)时触发。
|
||||||
|
- `destroy`:窗口被彻底销毁时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "app_window",
|
||||||
|
"widgettype": "PopupWindow",
|
||||||
|
"options": {
|
||||||
|
"title": "我的应用", // 窗口标题
|
||||||
|
"icon": "/resources/icons/app.png", // 标题栏左侧图标路径
|
||||||
|
"width": "60%", // 宽度百分比
|
||||||
|
"height": "70%", // 高度百分比
|
||||||
|
"movable": true, // 可拖动标题栏移动
|
||||||
|
"resizable": true, // 可调整大小
|
||||||
|
"modal": false, // 非模态,允许后台交互
|
||||||
|
"auto_open": true // 创建即打开
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "HtmlView",
|
||||||
|
"options": {
|
||||||
|
"html": "<div style='padding:20px;'>欢迎使用我的应用程序!</div>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "refresh_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "app_window",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/ui/myapp.content.ui", // 动态加载新内容
|
||||||
|
"method": "GET",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "log_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "app_window",
|
||||||
|
"script": "console.log('用户在窗口中点击了日志按钮');",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明**:
|
||||||
|
> - `PopupWindow` 提供标准窗口行为:最小化、关闭、全屏。
|
||||||
|
> - 工具栏按钮由 `IconBar` 实现,内置 delete/minimize/fullscreen 功能。
|
||||||
|
> - 最小化后可通过全局 `bricks.app.mwins` 列表恢复。
|
||||||
|
> - 支持通过 `urlwidget` 动态刷新内容,实现模块化加载。
|
||||||
|
> - 适合构建多窗口 Web 应用,如 IDE、管理系统等。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# WindowsPanel
|
||||||
|
|
||||||
|
任务栏式窗口管理面板,列出所有最小化的 `PopupWindow` 并提供恢复功能。属于**容器控件**,继承自 `bricks.Popup`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `del_window(event)`:处理点击某个窗口项时将其恢复并从列表中移除。
|
||||||
|
- (构造函数中自动初始化数据源与事件绑定)
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `record_click`:当用户点击某个窗口记录项时触发(来自 `Cols` 控件)。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "windows_panel",
|
||||||
|
"widgettype": "WindowsPanel",
|
||||||
|
"options": {
|
||||||
|
"archor": "br", // 锚定在右下角
|
||||||
|
"width": "200px",
|
||||||
|
"height": "300px",
|
||||||
|
"movable": true,
|
||||||
|
"resizable": false,
|
||||||
|
"modal": false,
|
||||||
|
"auto_open": false // 不自动打开,由快捷键或按钮触发
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "taskbar_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "windows_panel",
|
||||||
|
"method": "open",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明**:
|
||||||
|
> - 此控件用于展示当前已最小化的所有 `PopupWindow` 实例。
|
||||||
|
> - 数据来源于 `bricks.app.mwins` 数组,在构造时自动映射为可视列表。
|
||||||
|
> - 每一项是一个图标 + 标题,点击即可还原对应窗口。
|
||||||
|
> - 常用于模拟操作系统任务栏功能。
|
||||||
|
> - 本身也是弹窗类型,点击外部可自动关闭(`auto_dismiss: true`)。
|
||||||
80
docs/ai/progressbar.md
Normal file
80
docs/ai/progressbar.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
```markdown
|
||||||
|
# ProgressBar
|
||||||
|
|
||||||
|
ProgressBar 是一个用于展示任务进度的普通控件,继承自 `bricks.HBox`,属于**容器类控件**(虽然它主要用于布局内部进度条元素,但其内部包含子控件),通过动态设置宽度来显示当前进度百分比。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `set_value(v)`
|
||||||
|
设置当前进度值,自动计算百分比并更新进度条视觉宽度。
|
||||||
|
参数:
|
||||||
|
- `v` (Number):当前进度值
|
||||||
|
|
||||||
|
- `set_css(className)`
|
||||||
|
继承自父类,用于设置控件的 CSS 类名,便于样式控制。
|
||||||
|
|
||||||
|
- `add_widget(widget)`
|
||||||
|
继承自 HBox,用于添加子控件(如内部的文本显示控件)。
|
||||||
|
|
||||||
|
- `set_style(property, value)`
|
||||||
|
设置内联样式,用于动态调整进度条宽度。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
该控件目前未定义自定义事件,依赖于父类 `HBox` 的基础事件机制(如渲染完成等)。可通过外部绑定监听用户交互行为(如 click 等)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "progress1",
|
||||||
|
"widgettype": "ProgressBar",
|
||||||
|
"options": {
|
||||||
|
"total_value": 100, // 总进度值
|
||||||
|
"bar_cwidth": 2 // 进度条高度(单位:行高)
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_start",
|
||||||
|
"event": "click",
|
||||||
|
"target": "progress1",
|
||||||
|
"method": "set_value",
|
||||||
|
"params": {
|
||||||
|
"v": 75
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "确认操作",
|
||||||
|
"message": "是否将进度设置为75%?",
|
||||||
|
"confirm_text": "确定",
|
||||||
|
"cancel_text": "取消"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `id`: 控件唯一标识符。
|
||||||
|
> - `widgettype`: 使用已注册的 `"ProgressBar"` 控件类型。
|
||||||
|
> - `options.total_value`: 定义最大进度值,用于百分比计算(示例中未在构造函数使用,实际应完善逻辑)。
|
||||||
|
> - `options.bar_cwidth`: 控制进度条高度,默认为 2 行高度。
|
||||||
|
> - `binds`: 绑定按钮点击事件,调用 `set_value` 方法更新进度。
|
||||||
|
> - `conform`: 在执行前弹出确认对话框,增强用户体验与安全性。
|
||||||
|
|
||||||
|
> ⚠️ 注意:原始源码中存在变量名错误(`current` 和 `total` 未定义),正确实现应为:
|
||||||
|
> ```js
|
||||||
|
> set_value(current, total = this.options.total_value) {
|
||||||
|
> const percentage = (current / total) * 100;
|
||||||
|
> const pzt = Math.max(0, Math.min(100, percentage));
|
||||||
|
> this.text_w.set_style('width', pzt + '%');
|
||||||
|
> }
|
||||||
|
> ```
|
||||||
|
> 建议在实际使用时修复此问题,并确保传入合理的 `total_value` 参数。
|
||||||
|
```
|
||||||
115
docs/ai/qaframe.md
Normal file
115
docs/ai/qaframe.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# QAFrame
|
||||||
|
|
||||||
|
QAFrame 是一个用于实现问答交互流程的容器控件,通常用于在线教育、测试或互动课程场景。它通过 WebSocket 与后端通信,接收题目、课件内容、答题结果等数据,并动态渲染对应的界面。该控件继承自 `bricks.VBox`,属于**容器控件**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 描述 |
|
||||||
|
|-------|------|
|
||||||
|
| `start_question_answer()` | 向服务器发送 `'qa_start'` 消息,启动问答流程。绑定在开始按钮点击事件上。 |
|
||||||
|
| `show_question(d)` | 接收题目数据并显示,更新当前题号和总题数,将题目描述(HTML/文本)渲染到主区域。 |
|
||||||
|
| `show_courseware(d)` | 根据传入的数据类型(video/audio/image/markdown),创建对应媒体控件并展示在主区域。 |
|
||||||
|
| `show_conform(d)` | 显示确认开始的提示按钮,供用户点击确认后进入下一阶段。 |
|
||||||
|
| `conform_start()` | 发送 `'conform_start'` 消息至 WebSocket,表示用户已确认准备就绪。 |
|
||||||
|
| `send_text_answer(e)` | 处理文本答案提交,从事件中提取文本内容并通过 WebSocket 发送给服务端。 |
|
||||||
|
| `send_audio_answer(e)` | 将录音 Blob 转为 Base64 编码,并以 `'audio_answer'` 类型发送给服务端。 |
|
||||||
|
| `build_input_widgets()` | 构建输入控件:文本输入框和语音录制按钮,添加到底部工具栏。 |
|
||||||
|
| `play_course()` | 根据配置的 courseware 类型播放课件内容(视频、音频、图片或 Markdown)。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 数据格式示例 |
|
||||||
|
|--------|---------|-------------|
|
||||||
|
| `onopen` (WebSocket) | WebSocket 连接建立时 | 自动触发 `start_question_answer()` |
|
||||||
|
| `onquestion` | 收到新题目消息时 | `{ type: "question", data: { q_desc: "...", total_q: 5, cur_q: 1 } }` |
|
||||||
|
| `oncourseware` | 收到课件推送时 | `{ type: "video", url: "/video/1.mp4" }` |
|
||||||
|
| `onaskstart` | 服务端要求用户确认是否准备好时 | 显示“Start?”按钮等待点击 |
|
||||||
|
| `record_ended` (AudioRecorder) | 用户完成录音时 | 触发 `send_audio_answer()` 发送音频数据 |
|
||||||
|
| `blur` (文本输入框) | 文本输入失去焦点时 | 触发 `send_text_answer()` 发送答案 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "qa_frame_main",
|
||||||
|
"widgettype": "QAFrame",
|
||||||
|
"options": {
|
||||||
|
// WebSocket 地址,用于实时通信
|
||||||
|
"ws_url": "wss://example.com/ws/qa-session",
|
||||||
|
|
||||||
|
// 可选参数,附加到 ws_url 后作为查询字符串
|
||||||
|
"ws_params": {
|
||||||
|
"session_id": "12345",
|
||||||
|
"user_id": "U001"
|
||||||
|
},
|
||||||
|
|
||||||
|
// 页面标题(可选)
|
||||||
|
"title": "智能问答练习",
|
||||||
|
|
||||||
|
// 描述信息(可选)
|
||||||
|
"description": "请认真作答每一道问题。",
|
||||||
|
|
||||||
|
// 初始课件配置(可选),支持多种类型
|
||||||
|
"courseware": {
|
||||||
|
"type": "markdown", // 支持 "audio", "video", "image", "markdown"
|
||||||
|
"url": "/static/intro.md", // 内容资源地址
|
||||||
|
"timeout": 10 // 展示超时时间(秒),0 表示无超时
|
||||||
|
},
|
||||||
|
|
||||||
|
// 其他 UI 配置项(如有)
|
||||||
|
"cheight": 6 // 占据高度(基于网格布局)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 子控件(此控件自身是容器,但一般不手动添加 subwidgets)
|
||||||
|
// 实际子组件由内部逻辑动态生成(如 main_w、top_w 等)
|
||||||
|
"subwidgets": [],
|
||||||
|
|
||||||
|
// 绑定事件:例如外部触发重新开始
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_restart",
|
||||||
|
"event": "click",
|
||||||
|
"target": "qa_frame_main",
|
||||||
|
"method": "start_question_answer",
|
||||||
|
"conform": {
|
||||||
|
"title": "确认重启?",
|
||||||
|
"message": "你确定要重新开始本次问答吗?",
|
||||||
|
"confirm_label": "确定",
|
||||||
|
"cancel_label": "取消"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "qa_frame_main",
|
||||||
|
"event": "onquestion",
|
||||||
|
"target": "console_logger",
|
||||||
|
"script": "console.log('New question received:', params.q_desc);",
|
||||||
|
"params": {
|
||||||
|
"q_desc": "{data.q_desc}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `ws_url` 必须为有效的 WebSocket 地址(`ws://` 或 `wss://`)。
|
||||||
|
> - `ws_params` 中的参数会自动拼接到连接 URL 上,便于身份验证或会话追踪。
|
||||||
|
> - `courseware` 字段定义初始加载的内容,可在连接后由服务端消息覆盖。
|
||||||
|
> - 所有 UI 更新均由 WebSocket 推送驱动,无需手动操作 DOM。
|
||||||
|
> - 使用 `binds` 可扩展与其他控件的交互行为,如日志记录、弹窗提醒等。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
💡 **使用建议:**
|
||||||
|
|
||||||
|
- 配合后台使用 Node.js / Python WebSocket 服务实现题库推送与评分逻辑。
|
||||||
|
- 在移动端注意音频录制权限处理。
|
||||||
|
- 可结合 `Popup` 控件实现更复杂的交互确认流程。
|
||||||
360
docs/ai/recorder.md
Normal file
360
docs/ai/recorder.md
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
# SysCamera
|
||||||
|
|
||||||
|
SysCamera 是一个用于从系统摄像头拍照的容器控件,继承自 `SysVideoRecorder`。它本质上是一个媒体录制弹窗控件的特化版本,将“录制视频”功能替换为“单次拍摄照片”,适用于需要用户拍照上传的场景(如头像设置、证件照采集等)。该控件属于**容器控件**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`switch_record()`**
|
||||||
|
重写了父类的录屏/录音切换方法,改为执行拍照操作。停止预览流任务,派发 `shot` 事件并携带拍摄的图片 URL 和 File 对象,随后关闭摄像头。
|
||||||
|
|
||||||
|
- **`show_picture()`**
|
||||||
|
继承自 `SysVideoRecorder`,通过 `ImageCapture.takePhoto()` 持续获取当前帧图像,并显示在内置的 Image 控件中,形成实时预览效果。
|
||||||
|
|
||||||
|
- **`close_recorder()`**
|
||||||
|
清理资源:取消定时任务、停止媒体流轨道、释放 DOM 元素,最后调用 `dismiss()` 隐藏弹窗。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`shot`**
|
||||||
|
当用户点击拍照按钮时触发。携带数据:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"url": "data:image/jpeg;base64,...", // 图片 Data URL
|
||||||
|
"file": FileObject // 图片对应的 File 实例
|
||||||
|
}
|
||||||
|
```
|
||||||
|
可用于上传或展示拍摄结果。
|
||||||
|
|
||||||
|
- **`record_started`**(继承)
|
||||||
|
启动预览流时触发,表示摄像头已打开。
|
||||||
|
|
||||||
|
- **`record_end`**(继承)
|
||||||
|
不适用此控件,不会触发。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "camera_popup",
|
||||||
|
"widgettype": "SysCamera",
|
||||||
|
"options": {
|
||||||
|
"title": "Take a Photo", // 弹窗标题
|
||||||
|
"width": 400, // 弹窗宽度
|
||||||
|
"height": 500, // 弹窗高度
|
||||||
|
"fps": 30 // 视频预览帧率
|
||||||
|
},
|
||||||
|
"subwidgets": [], // SysCamera 自行管理子控件,无需手动定义
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "open_camera_btn", // 假设页面上有一个按钮 ID 为 open_camera_btn
|
||||||
|
"event": "click", // 点击时打开摄像头
|
||||||
|
"target": "camera_popup",
|
||||||
|
"method": "present" // 显示弹窗
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "camera_popup",
|
||||||
|
"event": "shot", // 监听拍照完成事件
|
||||||
|
"target": "photo_preview_img", // 假设有一个 Image 控件用于显示照片
|
||||||
|
"method": "set_url", // 调用 set_url 方法更新图片
|
||||||
|
"datawidget": "camera_popup", // 数据来源是 camera_popup
|
||||||
|
"datamethod": "getValue", // getValue 应返回 { url: ..., file: ... }
|
||||||
|
"dataparams": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "camera_popup",
|
||||||
|
"event": "shot",
|
||||||
|
"script": "console.log('Photo taken:', params.file.name); uploadFile(params.file);",
|
||||||
|
"params": {
|
||||||
|
"file": "{source.file}" // 使用表达式注入文件对象
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `SysCamera` 控件自动构建内部 UI(包括预览区和拍照按钮),开发者只需配置选项并绑定事件。
|
||||||
|
> - `present()` 方法由 `Popup` 基类提供,用于显示模态窗口。
|
||||||
|
> - `binds` 中监听 `shot` 事件后,可将图片传递给其他控件或执行上传逻辑。
|
||||||
|
> - 利用 `script` 类型绑定可以实现复杂业务逻辑,例如调用全局上传函数 `uploadFile`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# WidgetRecorder
|
||||||
|
|
||||||
|
WidgetRecorder 是一个用于录制指定 HTML 媒体元素(如 `<video>` 或 `<audio>`)内容的容器控件,继承自 `MediaRecorder`。它允许开发者选择某个播放中的媒体组件进行录制,适用于课程录制、音频剪辑等场景。该控件属于**容器控件**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`open_recorder()`**
|
||||||
|
初始化录制环境。根据 `options.widgetid` 找到目标媒体控件,检查其标签类型(`VIDEO` 或 `AUDIO`),然后调用 `.captureStream()` 获取媒体流,启用录制按钮。
|
||||||
|
|
||||||
|
- **`switch_record()`**
|
||||||
|
切换录制状态:开始或停止录制。开始时创建 `MediaRecorder` 实例并启动;停止时触发 `record_end` 事件并传出 Blob URL 和 File。
|
||||||
|
|
||||||
|
- **`close_recorder()`**
|
||||||
|
停止录制任务和媒体流,隐藏弹窗。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`record_started`**
|
||||||
|
开始录制时触发,可用于禁用按钮或提示用户。
|
||||||
|
|
||||||
|
- **`record_end`**
|
||||||
|
录制结束后触发,携带以下数据:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"url": "blob:http://...", // 可用于 `<audio>` 或 `<video>` 标签播放
|
||||||
|
"file": FileObject // 可用于上传
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "recorder_popup",
|
||||||
|
"widgettype": "WidgetRecorder",
|
||||||
|
"options": {
|
||||||
|
"title": "Record Media",
|
||||||
|
"width": 300,
|
||||||
|
"height": 200,
|
||||||
|
"widgetid": "main_video_player" // 要录制的目标视频控件 ID
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "start_record_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "recorder_popup",
|
||||||
|
"method": "present"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "recorder_popup",
|
||||||
|
"event": "record_end",
|
||||||
|
"target": "playback_preview",
|
||||||
|
"method": "set_url",
|
||||||
|
"datawidget": "recorder_popup",
|
||||||
|
"datamethod": "getValue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "registerfunction",
|
||||||
|
"wid": "recorder_popup",
|
||||||
|
"event": "record_end",
|
||||||
|
"rfname": "saveUserRecording",
|
||||||
|
"params": {
|
||||||
|
"userid": 12345,
|
||||||
|
"recording": "{source.file}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - 必须传入 `widgetid` 指向一个实际存在的媒体控件。
|
||||||
|
> - 支持录制 `<video>` 输出 mp4,`<audio>` 输出 wav。
|
||||||
|
> - `captureStream()` 是现代浏览器支持的标准 API,用于捕获元素播放的内容。
|
||||||
|
> - 使用 `registerfunction` 可调用注册过的全局函数处理录制结果。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# SysAudioRecorder
|
||||||
|
|
||||||
|
SysAudioRecorder 是一个用于录制用户麦克风音频的容器控件,继承自 `MediaRecorder`。它可以捕获用户的语音输入并将其转换为 WAV 格式文件,适合语音留言、录音笔记等应用。该控件属于**容器控件**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`open_recorder()`**
|
||||||
|
请求用户授权访问麦克风(`navigator.mediaDevices.getUserMedia`),获取音频流,并启用录制按钮。
|
||||||
|
|
||||||
|
- **`blob_convert(webmBlob)`**
|
||||||
|
将浏览器默认生成的 WebM 格式音频解码为 PCM 数据,再编码为标准 WAV 格式,确保兼容性。
|
||||||
|
|
||||||
|
- **`encodeWAV(audioBuffer)`**
|
||||||
|
编码 AudioBuffer 为 WAV 文件的二进制格式,构造符合 RIFF/WAVE 规范的 Blob。
|
||||||
|
|
||||||
|
- **`interleave(left, right)`**
|
||||||
|
合并左右声道数据,生成立体声 PCM 浮点数组。
|
||||||
|
|
||||||
|
- **`writeString(view, offset, string)`**
|
||||||
|
向 DataView 写入 ASCII 字符串,用于构建 WAV 头部信息。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`record_started`**
|
||||||
|
麦克风开始录制时触发。
|
||||||
|
|
||||||
|
- **`record_end`**
|
||||||
|
停止录制后触发,携带:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"url": "blob:...", // 可播放的 blob URL
|
||||||
|
"file": WAV_File_Object // 16bit PCM WAV 格式的 File
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "mic_recorder",
|
||||||
|
"widgettype": "SysAudioRecorder",
|
||||||
|
"options": {
|
||||||
|
"title": "Voice Recorder",
|
||||||
|
"width": 350,
|
||||||
|
"height": 180
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "mic_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "mic_recorder",
|
||||||
|
"method": "present"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "mic_recorder",
|
||||||
|
"event": "record_end",
|
||||||
|
"target": "audio_player",
|
||||||
|
"method": "set_url",
|
||||||
|
"datawidget": "mic_recorder",
|
||||||
|
"datamethod": "getValue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "mic_recorder",
|
||||||
|
"event": "record_started",
|
||||||
|
"target": "status_label",
|
||||||
|
"method": "set_text",
|
||||||
|
"rtdata": {
|
||||||
|
"text": "Recording..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "mic_recorder",
|
||||||
|
"event": "record_end",
|
||||||
|
"target": "status_label",
|
||||||
|
"method": "set_text",
|
||||||
|
"rtdata": {
|
||||||
|
"text": "Ready"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - 默认使用 WebM 容器录制,但最终输出为更通用的 WAV 格式。
|
||||||
|
> - `encodeWAV` 实现了完整的 WAV 文件头封装,保证跨平台播放兼容性。
|
||||||
|
> - 可结合 `AudioContext` 实现可视化波形图增强用户体验。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# SysVideoRecorder
|
||||||
|
|
||||||
|
SysVideoRecorder 是一个用于录制用户摄像头及麦克风的容器控件,继承自 `MediaRecorder`。它能同时录制音视频并保存为 MP4 文件,适用于视频通话录制、面试录像等场景。该控件属于**容器控件**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`open_recorder()`**
|
||||||
|
请求音视频权限,获取媒体流,初始化 `ImageCapture` 用于逐帧抓取画面以供预览。
|
||||||
|
|
||||||
|
- **`show_picture()`**
|
||||||
|
定期调用 `imageCapture.takePhoto()` 获取当前帧并渲染到 `Image` 控件中,实现低延迟预览。
|
||||||
|
|
||||||
|
- **`close_recorder()`**
|
||||||
|
释放所有资源,包括预览任务和媒体流轨道。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`record_started`**
|
||||||
|
开始录制时触发。
|
||||||
|
|
||||||
|
- **`record_end`**
|
||||||
|
结束录制后触发,携带 MP4 格式的 Blob URL 和 File 对象。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "video_recorder",
|
||||||
|
"widgettype": "SysVideoRecorder",
|
||||||
|
"options": {
|
||||||
|
"title": "Video Recorder",
|
||||||
|
"width": 500,
|
||||||
|
"height": 600
|
||||||
|
},
|
||||||
|
"subwidgets": [],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "record_video_btn",
|
||||||
|
"event": "click",
|
||||||
|
"target": "video_recorder",
|
||||||
|
"method": "present"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "video_recorder",
|
||||||
|
"event": "record_end",
|
||||||
|
"target": "video_preview",
|
||||||
|
"method": "set_url",
|
||||||
|
"datawidget": "video_recorder",
|
||||||
|
"datamethod": "getValue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "video_recorder",
|
||||||
|
"event": "record_end",
|
||||||
|
"target": "upload_container",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/upload_form",
|
||||||
|
"params": {
|
||||||
|
"type": "video",
|
||||||
|
"filename": "user_interview.mp4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - 使用 `getUserMedia({audio:true, video:true})` 同时获取音视频流。
|
||||||
|
> - 预览使用 `ImageCapture` API 提高清晰度和响应速度。
|
||||||
|
> - 录制完成后可通过 `urlwidget` 动态加载上传表单,实现流程自动化。
|
||||||
|
> - 输出文件为 `video/mp4` 类型,适配大多数播放器和服务器处理逻辑。
|
||||||
240
docs/ai/registerfunction.md
Normal file
240
docs/ai/registerfunction.md
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
# MyButton
|
||||||
|
|
||||||
|
该控件是一个普通按钮控件,用于触发用户交互行为。类型为**普通控件**,继承自 `JsWidget`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `setValue(text)`:设置按钮显示文本。
|
||||||
|
- `getValue()`:获取按钮当前显示的文本。
|
||||||
|
- `enable()`:启用按钮(可点击)。
|
||||||
|
- `disable()`:禁用按钮(不可点击)。
|
||||||
|
- `show()`:显示按钮。
|
||||||
|
- `hide()`:隐藏按钮。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `'click'`:当用户点击按钮时触发。
|
||||||
|
- `'mousedown'`:鼠标按下时触发。
|
||||||
|
- `'mouseup'`:鼠标释放时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "btn_submit", // 控件唯一标识
|
||||||
|
"widgettype": "button", // 控件类型:button 是 bricks 中已注册的控件
|
||||||
|
"options": {
|
||||||
|
"text": "提交", // 按钮初始显示文本
|
||||||
|
"disabled": false, // 是否禁用,默认不禁用
|
||||||
|
"cssclass": "primary-btn" // 自定义 CSS 类名
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method", // 动作类型:调用方法
|
||||||
|
"wid": "btn_submit", // 触发组件 ID
|
||||||
|
"event": "click", // 监听点击事件
|
||||||
|
"target": "msg_box", // 目标组件 ID
|
||||||
|
"method": "setValue", // 调用目标的方法
|
||||||
|
"params": {
|
||||||
|
"value": "数据已提交!" // 方法参数
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script", // 执行脚本动作
|
||||||
|
"wid": "btn_submit",
|
||||||
|
"event": "click",
|
||||||
|
"target": "btn_submit",
|
||||||
|
"script": "async function({ widget }) { console.log('按钮被点击:', widget.getValue()); }",
|
||||||
|
"params": {
|
||||||
|
"widget": "{self}" // 特殊变量,指向当前控件实例
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event", // 派发自定义事件
|
||||||
|
"wid": "btn_submit",
|
||||||
|
"event": "click",
|
||||||
|
"target": "form_panel",
|
||||||
|
"dispatch_event": "form.submitted", // 向 form_panel 派发 form.submitted 事件
|
||||||
|
"params": {
|
||||||
|
"submitTime": "{now}", // 当前时间戳占位符
|
||||||
|
"source": "btn_submit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# ContainerPanel
|
||||||
|
|
||||||
|
该控件是一个容器控件,用于容纳其他子控件并进行布局管理。类型为**容器控件**,继承自 `JsWidget`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `addSubwidget(widgetJson)`:动态添加一个子控件。
|
||||||
|
- `removeSubwidget(widgetId)`:根据 ID 移除子控件。
|
||||||
|
- `getSubwidget(id)`:获取指定 ID 的子控件实例。
|
||||||
|
- `show()`:显示整个容器。
|
||||||
|
- `hide()`:隐藏整个容器。
|
||||||
|
- `setLayout(layoutType)`:设置布局方式(如 'vertical', 'horizontal')。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `'init'`:容器初始化完成后触发。
|
||||||
|
- `'widgetadded'`:当有新控件加入时触发。
|
||||||
|
- `'widgetremoved'`:当控件被移除时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "form_panel", // 容器控件 ID
|
||||||
|
"widgettype": "panel", // panel 是 bricks 中支持的容器控件
|
||||||
|
"options": {
|
||||||
|
"title": "用户信息表单", // 面板标题
|
||||||
|
"collapsible": true, // 可折叠
|
||||||
|
"layout": "vertical", // 垂直布局排列子控件
|
||||||
|
"cssstyle": {
|
||||||
|
"padding": "15px",
|
||||||
|
"border": "1px solid #ccc",
|
||||||
|
"border-radius": "8px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subwidgets": [ // 子控件数组
|
||||||
|
{
|
||||||
|
"id": "input_name",
|
||||||
|
"widgettype": "textfield",
|
||||||
|
"options": {
|
||||||
|
"label": "姓名",
|
||||||
|
"placeholder": "请输入您的姓名",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "input_email",
|
||||||
|
"widgettype": "textfield",
|
||||||
|
"options": {
|
||||||
|
"label": "邮箱",
|
||||||
|
"type": "email",
|
||||||
|
"placeholder": "example@domain.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_save",
|
||||||
|
"widgettype": "button",
|
||||||
|
"options": {
|
||||||
|
"text": "保存",
|
||||||
|
"cssclass": "success"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget", // 加载远程组件作为弹窗
|
||||||
|
"wid": "btn_save",
|
||||||
|
"event": "click",
|
||||||
|
"target": "Popup", // 特殊目标:打开弹窗
|
||||||
|
"mode": "append",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/widgets/confirm-dialog.ui", // 远程 UI 文件地址
|
||||||
|
"method": "GET",
|
||||||
|
"params": {
|
||||||
|
"action": "save_user"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "form_panel",
|
||||||
|
"event": "init",
|
||||||
|
"target": "logger",
|
||||||
|
"dispatch_event": "log.info",
|
||||||
|
"params": {
|
||||||
|
"message": "表单面板初始化完成",
|
||||||
|
"component": "form_panel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# DynamicLoader
|
||||||
|
|
||||||
|
该控件用于从服务器动态加载其他控件,实现模块化界面加载。类型为**普通控件(实际为逻辑控制器)**,继承自 `JsWidget`,常配合 `urlwidget` 使用。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `load(url, params, mode)`:加载远程 UI 组件。
|
||||||
|
- `refresh()`:重新加载当前资源。
|
||||||
|
- `clearTarget(targetId)`:清空目标容器内容。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `'loadstart'`:开始加载远程组件时触发。
|
||||||
|
- `'loadsuccess'`:加载成功后触发。
|
||||||
|
- `'loaderror'`:加载失败时触发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "loader_dashboard",
|
||||||
|
"widgettype": "urlwidget", // 特殊控件类型:用于加载远程组件
|
||||||
|
"options": {
|
||||||
|
"url": "/ui/modules/dashboard.ui", // 要加载的远程 .ui 文件路径
|
||||||
|
"method": "POST", // 使用 POST 请求
|
||||||
|
"params": {
|
||||||
|
"userRole": "{session.user.role}", // 动态参数:来自会话的角色信息
|
||||||
|
"tab": "overview"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks", // 在本地创建一个新的 bricks 组件
|
||||||
|
"wid": "loader_dashboard",
|
||||||
|
"event": "loadsuccess", // 加载成功后执行
|
||||||
|
"target": "status_bar",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "label",
|
||||||
|
"id": "lbl_status",
|
||||||
|
"options": {
|
||||||
|
"text": "仪表盘加载成功",
|
||||||
|
"cssclass": "status-success"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "loader_dashboard",
|
||||||
|
"event": "loaderror",
|
||||||
|
"target": "status_bar",
|
||||||
|
"method": "setValue",
|
||||||
|
"params": {
|
||||||
|
"value": "加载失败,请重试"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "registerfunction",
|
||||||
|
"wid": "loader_dashboard",
|
||||||
|
"event": "loadsuccess",
|
||||||
|
"target": "loader_dashboard",
|
||||||
|
"rfname": "trackPageView", // 调用全局注册函数
|
||||||
|
"params": {
|
||||||
|
"page": "dashboard",
|
||||||
|
"time": "{now}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - `{session.user.role}` 和 `{now}` 是 bricks 支持的运行时变量占位符。
|
||||||
|
> - `urlwidget` 类型控件不渲染自身 UI,而是将远程返回的 JSON 渲染到目标容器中。
|
||||||
|
> - `registerfunction` 需提前通过 `bricks.RF.register('trackPageView', fn)` 注册函数。
|
||||||
90
docs/ai/running.md
Normal file
90
docs/ai/running.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Running
|
||||||
|
|
||||||
|
用于显示一个运行中的状态提示控件,通常在异步操作(如数据加载、文件上传等)期间展示给用户。该控件为**容器控件**,继承自 `bricks.BaseModal`,具备模态弹窗的基本行为,并内置了一个动态刷新的时间显示和动图图标。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`dismiss()`**
|
||||||
|
重写自父类 `BaseModal`,用于关闭当前运行提示窗口。在关闭前会调用内部 `BaseRunning` 实例的 `stop_timepass()` 方法,停止定时器以释放资源。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件。但作为模态框,其打开与关闭受 `auto_open: true` 控制,在实例化时自动触发显示。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "running_indicator",
|
||||||
|
"widgettype": "Running",
|
||||||
|
"options": {
|
||||||
|
"icon": "imgs/loading_custom.gif", // 自定义加载图标路径,可选
|
||||||
|
"target": "main_container" // 指定渲染到哪个容器中(可由 bind 的 target 传递)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ 注释说明:
|
||||||
|
> - `"id"`:控件唯一标识,便于后续通过 ID 引用或销毁。
|
||||||
|
> - `"widgettype": "Running"`:表示使用已注册的 `Running` 控件。
|
||||||
|
> - `"options.icon"`:可选参数,指定动效图标 URL;若不传则使用默认资源 `imgs/running.gif`。
|
||||||
|
> - `"options.target"`:虽然在此未直接生效,但在实际绑定中可通过 `binds` 的 `target` 字段指定插入位置。
|
||||||
|
> - `auto_open: true` 在源码中硬编码设置,意味着一旦创建即自动弹出显示。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 使用场景示例(结合 binds)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "btn_load_data",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"text": "开始加载",
|
||||||
|
"i18n": false
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "btn_load_data",
|
||||||
|
"event": "click",
|
||||||
|
"target": "Popup",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Running",
|
||||||
|
"id": "run_task",
|
||||||
|
"options": {
|
||||||
|
"icon": "imgs/loading.gif"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "btn_load_data",
|
||||||
|
"event": "click",
|
||||||
|
"target": "content_area",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/load_content.ui",
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "确认操作",
|
||||||
|
"message": "即将加载新内容,是否继续?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 🔍 示例说明:
|
||||||
|
> - 点击按钮后:
|
||||||
|
> 1. 首先在 `Popup` 中显示 `Running` 加载动画;
|
||||||
|
> 2. 同时向服务器请求 `/api/load_content.ui`,加载完成后替换 `content_area` 内容;
|
||||||
|
> 3. 请求发起前弹出确认对话框(由 `conform` 触发);
|
||||||
|
> 4. 当内容加载完毕后,开发者应在响应逻辑中手动关闭 `Running` 提示(例如通过 `bricks.get_widget('run_task').dismiss()`)。
|
||||||
206
docs/ai/scroll.md
Normal file
206
docs/ai/scroll.md
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
# VScrollPanel
|
||||||
|
|
||||||
|
用于创建垂直滚动容器控件,支持在滚动到接近顶部或底部时触发特定事件。该控件为**容器控件**,继承自 `VBox`,可包含子控件,并具备自动滚动行为与阈值检测功能。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `scroll_handle(event)`
|
||||||
|
内部滚动事件处理器,负责监控滚动位置并判断是否达到预设的上下阈值,若达到则派发对应事件。
|
||||||
|
|
||||||
|
- `bind(event, handler)`(继承自基类)
|
||||||
|
绑定 DOM 事件,此处用于监听 `'scroll'` 事件。
|
||||||
|
|
||||||
|
- `dispatch(event_name, data)`(继承自基类)
|
||||||
|
派发自定义事件,如 `min_threshold` 或 `max_threshold`。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `min_threshold`
|
||||||
|
当滚动条接近顶部(滚动位置小于最小阈值)时触发,常用于加载上一页数据。
|
||||||
|
|
||||||
|
- `max_threshold`
|
||||||
|
当滚动条接近底部(滚动位置超过最大阈值)时触发,常用于实现“滚动到底自动加载更多”功能。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "scroll_container",
|
||||||
|
"widgettype": "VScrollPanel",
|
||||||
|
"options": {
|
||||||
|
"css": "my-scroll-area", // 自定义样式类
|
||||||
|
"min_threshold": 0.02, // 滚动到顶部附近 2% 时触发 min_threshold
|
||||||
|
"max_threshold": 0.95, // 滚动到距离底部 5% 时触发 max_threshold
|
||||||
|
"width": "100%", // 宽度占满父容器
|
||||||
|
"height": "500px" // 固定高度以启用滚动
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "item_1",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "这是第1项内容",
|
||||||
|
"css": "list-item"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "item_2",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "这是第2项内容",
|
||||||
|
"css": "list-item"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "item_3",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "这是第3项内容",
|
||||||
|
"css": "list-item"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 更多项目可动态加载
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "scroll_container",
|
||||||
|
"event": "max_threshold",
|
||||||
|
"target": "data_loader",
|
||||||
|
"dispatch_event": "load_more",
|
||||||
|
"params": {
|
||||||
|
"page": "+1"
|
||||||
|
},
|
||||||
|
"conform": null,
|
||||||
|
"rtdata": {
|
||||||
|
"source": "user_list"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "scroll_container",
|
||||||
|
"event": "min_threshold",
|
||||||
|
"target": "console_logger",
|
||||||
|
"script": "console.log('用户已滚动到顶部,准备刷新列表')",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `VScrollPanel` 设置了滚动阈值后,会在用户滚动接近顶部或底部时自动派发事件。
|
||||||
|
> - `binds` 中通过监听 `max_threshold` 实现“无限滚动”逻辑,调用其他组件加载更多数据。
|
||||||
|
> - 使用 `script` 类型绑定可在触底时执行调试脚本。
|
||||||
|
> - 子控件数组 `subwidgets` 可预先写入部分内容,后续可通过事件动态追加。
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# HScrollPanel
|
||||||
|
|
||||||
|
用于创建水平滚动容器控件,支持在滚动到最左端或最右端附近时触发指定事件。该控件为**容器控件**,继承自 `HBox`,适用于横向滑动布局场景(如轮播图、标签栏等)。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `scroll_handle(event)`
|
||||||
|
处理水平方向的滚动事件,计算当前滚动比例并与阈值比较。
|
||||||
|
|
||||||
|
- `bind(event, handler)`
|
||||||
|
监听 `'scroll'` 事件以实现实时位置判断。
|
||||||
|
|
||||||
|
- `dispatch(event_name, data)`
|
||||||
|
触发 `min_threshold`(左侧极限)和 `max_threshold`(右侧极限)事件。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `min_threshold`
|
||||||
|
滚动条位于最左侧附近时触发,表示无法继续向左滚动。
|
||||||
|
|
||||||
|
- `max_threshold`
|
||||||
|
滚动条到达最右侧附近时触发,可用于加载更多横向内容。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "horizontal_scroller",
|
||||||
|
"widgettype": "HScrollPanel",
|
||||||
|
"options": {
|
||||||
|
"css": "gallery-container", // 添加自定义样式
|
||||||
|
"min_threshold": 0.01, // 接近起点 1% 触发
|
||||||
|
"max_threshold": 0.99, // 接近终点 1% 触发
|
||||||
|
"width": "100%",
|
||||||
|
"height": "200px",
|
||||||
|
"overflow": "auto"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "img_1",
|
||||||
|
"widgettype": "Image",
|
||||||
|
"options": {
|
||||||
|
"src": "/images/banner1.jpg",
|
||||||
|
"width": "180px",
|
||||||
|
"height": "180px",
|
||||||
|
"css": "gallery-item"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "img_2",
|
||||||
|
"widgettype": "Image",
|
||||||
|
"options": {
|
||||||
|
"src": "/images/banner2.jpg",
|
||||||
|
"width": "180px",
|
||||||
|
"height": "180px",
|
||||||
|
"css": "gallery-item"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "img_3",
|
||||||
|
"widgettype": "Image",
|
||||||
|
"options": {
|
||||||
|
"src": "/images/banner3.jpg",
|
||||||
|
"width": "180px",
|
||||||
|
"height": "180px",
|
||||||
|
"css": "gallery-item"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "horizontal_scroller",
|
||||||
|
"event": "max_threshold",
|
||||||
|
"target": "Popup",
|
||||||
|
"mode": "append",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "已经是最后一张图片了!",
|
||||||
|
"css": "toast-message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"duration": 2000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "horizontal_scroller",
|
||||||
|
"event": "min_threshold",
|
||||||
|
"target": "analytics_tracker",
|
||||||
|
"method": "trackEvent",
|
||||||
|
"params": {
|
||||||
|
"category": "Gallery",
|
||||||
|
"action": "scroll_to_start"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `HScrollPanel` 常用于图像画廊、水平菜单等需要横向滚动的界面。
|
||||||
|
> - 当滚动到最右边时,使用 `bricks` 动作弹出提示信息(追加到 Popup 容器中)。
|
||||||
|
> - 滚动回起始位置时,调用分析组件记录用户行为。
|
||||||
|
> - 所有子控件应设置固定宽度以便形成可滚动内容流。
|
||||||
91
docs/ai/splitter.md
Normal file
91
docs/ai/splitter.md
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# Splitter
|
||||||
|
|
||||||
|
Splitter 是一个用于在界面中插入水平分隔线的**普通控件**,继承自 `bricks.JsWidget`。它不包含任何子控件,主要用于视觉上分割不同区域的内容,提升界面可读性。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`create()`**
|
||||||
|
创建 DOM 元素(`<hr>` 标签),作为分隔线渲染到页面中。
|
||||||
|
|
||||||
|
- **`_create(tagName)`** *(继承自 JsWidget)*
|
||||||
|
辅助方法,用于创建指定标签的 DOM 元素,并设置基础属性。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
Splitter 控件本身不触发或监听任何用户交互事件(如 click、hover 等),仅作为静态展示元素使用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "splitter_01", // 控件唯一标识
|
||||||
|
"widgettype": "Splitter", // 控件类型:必须为注册过的控件名
|
||||||
|
"options": {}, // 构造参数,Splitter无需特殊配置
|
||||||
|
"binds": [] // 无事件绑定需求,保持空数组
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **说明:**
|
||||||
|
> 上述 JSON 可以直接嵌入 `.ui` 文件中,在容器内使用以添加一条水平分隔线。由于 Splitter 是普通控件,不能包含 `subwidgets` 字段。
|
||||||
|
|
||||||
|
### 实际应用场景示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "container_main",
|
||||||
|
"widgettype": "VBox", // 容器控件,垂直布局
|
||||||
|
"options": {
|
||||||
|
"style": "padding: 10px;"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "label_title",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "基本信息"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "splitter_section1",
|
||||||
|
"widgettype": "Splitter",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "form_basic",
|
||||||
|
"widgettype": "Form",
|
||||||
|
"options": {
|
||||||
|
"fields": [
|
||||||
|
{ "name": "name", "label": "姓名" },
|
||||||
|
{ "name": "age", "label": "年龄" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "splitter_section2",
|
||||||
|
"widgettype": "Splitter",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "label_other",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "其他信息"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 📌 **注释说明:**
|
||||||
|
> 在 VBox 垂直布局中,通过插入多个 `Splitter` 控件来分隔“基本信息”与“其他信息”区块,增强界面结构清晰度。每个 `Splitter` 都是一个轻量级的视觉装饰控件,不影响逻辑功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
💡 **提示:**
|
||||||
|
若需自定义样式(如虚线、颜色、边距等),可通过扩展 Splitter 类或在后续版本中支持 `options.style` 传入 CSS 样式字符串实现。当前基础版仅生成默认 `<hr>` 元素。
|
||||||
89
docs/ai/streaming_audio.md
Normal file
89
docs/ai/streaming_audio.md
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# StreamAudio
|
||||||
|
|
||||||
|
本控件用于实现基于 Web Audio API 的实时语音采集与流式传输功能,通常用于语音识别(ASR)场景。类型为**容器控件**,继承自 `bricks.VBox`,具备垂直布局能力,并内置按钮控制录音启停、文本显示识别结果。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `toggle_status()`
|
||||||
|
切换录音状态:若正在录音则调用 `stop()`,否则调用 `start()`。
|
||||||
|
|
||||||
|
- `start()`
|
||||||
|
启动录音流程,更新按钮文字为“stop”,并延迟调用 `_start` 方法。
|
||||||
|
|
||||||
|
- `_start()` *(异步)*
|
||||||
|
实际启动逻辑:
|
||||||
|
- 若存在其他 VAD 实例,则先停止;
|
||||||
|
- 创建新的 MicVAD 实例,监听语音结束事件;
|
||||||
|
- 启动 UpStreaming 流式上传连接到指定服务器 URL;
|
||||||
|
- 开始接收服务端返回的识别结果。
|
||||||
|
|
||||||
|
- `stop()`
|
||||||
|
停止录音,将按钮文字改回“start”,并延迟执行 `_stop`。
|
||||||
|
|
||||||
|
- `_stop()` *(异步)*
|
||||||
|
结束上传流、暂停 VAD 录音,并清理全局引用。
|
||||||
|
|
||||||
|
- `receive_data()` *(异步)*
|
||||||
|
持续从服务端响应流中读取数据行,解析 JSON 并更新显示文本内容。
|
||||||
|
|
||||||
|
- `handle_audio(audio)`
|
||||||
|
处理捕获到的音频片段,将其转为 Base64 编码后通过 `UpStreaming` 发送至服务端。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `click` 事件绑定在内部的 `Button` 控件上,触发 `toggle_status` 方法以切换录音状态。
|
||||||
|
- 自定义语音事件由 `MicVAD` 触发 `onSpeechEnd` 回调,交由 `handle_audio` 处理。
|
||||||
|
- 数据接收过程中会持续处理来自服务端的流式消息,无显式事件暴露给外部。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "stream_audio_widget",
|
||||||
|
"widgettype": "StreamAudio",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/asr/stream", // 指定 ASR 流式识别接口地址
|
||||||
|
"name": "asr_text" // 可选,用于标识该组件名称
|
||||||
|
},
|
||||||
|
"subwidgets": [], // 本控件自行管理子控件,无需手动定义
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "stream_audio_widget",
|
||||||
|
"event": "click",
|
||||||
|
"target": "stream_audio_widget",
|
||||||
|
"method": "toggle_status",
|
||||||
|
"params": {},
|
||||||
|
"conform": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "stream_audio_widget",
|
||||||
|
"event": "speech_end",
|
||||||
|
"target": "Popup",
|
||||||
|
"dispatch_event": "show_notification",
|
||||||
|
"params": {
|
||||||
|
"message": "语音片段已发送"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `widgettype: "StreamAudio"` 表示使用注册的 StreamAudio 控件;
|
||||||
|
> - `options.url` 是必须项,指明音频流上传的目标后端接口;
|
||||||
|
> - `binds` 中第一个条目确保点击按钮时触发状态切换;
|
||||||
|
> - 第二个 `event` 类型的 bind 演示了如何在语音结束时向弹窗系统派发通知事件;
|
||||||
|
> - 控件自动创建内部结构(按钮、填充器、文本框),开发者无需关心 `subwidgets` 细节;
|
||||||
|
> - 此控件也兼容别名 `"ASRText"`,因在工厂中做了双重注册。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 💡 提示:使用此控件前需确保浏览器支持 Web Audio API 和 `MediaRecorder`,且后端 `/api/asr/stream` 支持 WebSocket 或 ReadableStream 流式交互。
|
||||||
194
docs/ai/svg.md
Normal file
194
docs/ai/svg.md
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
# Svg
|
||||||
|
|
||||||
|
用于显示可缩放矢量图形(SVG),支持颜色动态替换、远程加载 SVG 内容以及闪烁动画效果。该控件继承自 `VBox`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `set_url(url)`
|
||||||
|
从指定 URL 加载 SVG 内容并渲染到当前控件中。若 `url` 为空,则清空内容。
|
||||||
|
|
||||||
|
- `set_color(color)`
|
||||||
|
设置 SVG 的填充颜色,并重新渲染带颜色的 SVG。
|
||||||
|
|
||||||
|
- `set_colored_svg(color)`
|
||||||
|
使用模板替换 `{color}` 变量,将原始 SVG 文本染色后插入 DOM。
|
||||||
|
|
||||||
|
- `start_blink()`
|
||||||
|
启动周期性闪烁动画(根据 `blinktime` 毫秒间隔切换显示与隐藏)。
|
||||||
|
|
||||||
|
- `end_blink()`
|
||||||
|
停止闪烁动画。
|
||||||
|
|
||||||
|
- `_blink()`
|
||||||
|
私有方法,实现实际的闪烁逻辑,通过 `schedule_once` 循环调用自身。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无内置公开事件,但可通过父类 `JsWidget` 继承的 `dispatch` 方法派发自定义事件。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "svg_icon",
|
||||||
|
"widgettype": "Svg",
|
||||||
|
"options": {
|
||||||
|
"url": "/assets/icons/home.svg", // 远程 SVG 文件地址
|
||||||
|
"rate": 1.5, // 缩放比例
|
||||||
|
"color": "#007BFF", // 图标颜色(可选,默认取自应用主题)
|
||||||
|
"blinktime": 500 // 闪烁间隔(毫秒),设置后自动开启闪烁
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "svg_icon",
|
||||||
|
"event": "click",
|
||||||
|
"target": "svg_icon",
|
||||||
|
"method": "end_blink",
|
||||||
|
"conform": {
|
||||||
|
"title": "确认停止",
|
||||||
|
"message": "是否停止闪烁?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注释:此控件适合用于需要动态变色或交互反馈的图标展示场景。通过 `url` 动态加载 SVG,结合 `color` 实现主题适配;`blinktime` 提供视觉提示功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# StatedSvg
|
||||||
|
|
||||||
|
一个状态切换型 SVG 控件,允许在多个预定义状态之间循环切换,每个状态对应不同的 SVG 图标。点击控件时触发状态变更。继承自 `Svg`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `set_state(state)`
|
||||||
|
切换到指定名称的状态,加载对应状态的 SVG 资源,并派发 `state_changed` 事件。
|
||||||
|
|
||||||
|
- `trigger(event)`
|
||||||
|
点击事件处理器,用于循环切换下一个状态(循环式切换)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `state_changed`
|
||||||
|
当状态发生变化时派发,携带新状态名作为参数。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "power_indicator",
|
||||||
|
"widgettype": "StatedSvg",
|
||||||
|
"options": {
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"state": "off",
|
||||||
|
"url": "/icons/power-off.svg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state": "on",
|
||||||
|
"url": "/icons/power-on.svg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"state": "standby",
|
||||||
|
"url": "/icons/power-standby.svg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"state": "off", // 初始状态
|
||||||
|
"color": "#FFFFFF",
|
||||||
|
"blinktime": 300 // 在 on 状态下可配合闪烁使用
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "power_indicator",
|
||||||
|
"event": "state_changed",
|
||||||
|
"target": "status_label",
|
||||||
|
"dispatch_event": "update_text",
|
||||||
|
"params": {
|
||||||
|
"text": "{data}" // data 为 state 值
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "power_indicator",
|
||||||
|
"event": "state_changed",
|
||||||
|
"target": "power_indicator",
|
||||||
|
"method": "start_blink",
|
||||||
|
"rtdata": {
|
||||||
|
"condition": "data === 'standby'" // 若状态为 standby,则开始闪烁
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注释:`StatedSvg` 适用于电源、模式、连接状态等具有明确状态阶段的图标控件。通过 `states` 数组配置各个状态及其对应的 SVG 路径,点击自动轮转。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# MultipleStateIcon
|
||||||
|
|
||||||
|
多状态图标控件,基于键值对形式管理多个状态和对应的 SVG URL。继承自 `Svg`,属于**普通控件**。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `set_state(state)`
|
||||||
|
根据传入的状态名,查找 `urls` 映射表中的 URL 并加载相应 SVG。
|
||||||
|
|
||||||
|
- `change_state(event)`
|
||||||
|
点击事件处理函数,按顺序切换到下一个状态(循环切换)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `state_changed`
|
||||||
|
状态改变后派发,携带当前状态名。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "mode_selector",
|
||||||
|
"widgettype": "MultipleStateIcon",
|
||||||
|
"options": {
|
||||||
|
"state": "day", // 初始状态
|
||||||
|
"urls": {
|
||||||
|
"day": "/icons/day-mode.svg",
|
||||||
|
"night": "/icons/night-mode.svg",
|
||||||
|
"auto": "/icons/auto-mode.svg"
|
||||||
|
},
|
||||||
|
"color": "#333333",
|
||||||
|
"rate": 1.2
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "mode_selector",
|
||||||
|
"event": "state_changed",
|
||||||
|
"target": "Popup",
|
||||||
|
"script": "console.log('切换到了', data.state); bricks.toast(`已切换至 ${data.state} 模式`);",
|
||||||
|
"params": {
|
||||||
|
"state": "{data}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "mode_selector",
|
||||||
|
"event": "click",
|
||||||
|
"target": "config_panel",
|
||||||
|
"mode": "append",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Label",
|
||||||
|
"id": "dynamic_label_{timestamp}",
|
||||||
|
"options": {
|
||||||
|
"text": "用户点击了模式图标"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注释:`MultipleStateIcon` 更适合以对象字面量方式组织状态映射关系,结构清晰易维护。常用于主题切换、视图模式选择等 UI 控件。结合 `binds` 可实现丰富的交互响应。
|
||||||
123
docs/ai/tab.md
Normal file
123
docs/ai/tab.md
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
# TabPanel
|
||||||
|
|
||||||
|
**用处**:`TabPanel` 是一个容器控件,用于实现多标签页界面布局,允许用户在多个子界面之间切换。常用于管理多个独立内容区域(如配置页面、数据面板等),提升界面空间利用率。
|
||||||
|
|
||||||
|
**类型**:容器控件,继承自 `bricks.Layout`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 参数 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `show_first_tab()` | 无 | 显示第一个标签页的内容,通常在初始化完成后调用 |
|
||||||
|
| `createToolbar()` | 无 | 创建顶部或侧边的标签工具栏(基于 `bricks.Toolbar`) |
|
||||||
|
| `show_tabcontent(event)` | event: 事件对象 | 异步加载并显示指定标签页的内容,支持缓存和动态构建 |
|
||||||
|
| `switch_content(w)` | w: widget 实例 | 切换当前显示的内容为指定控件,并触发相关事件 |
|
||||||
|
| `add_tab(desc)` | desc: 标签描述对象 | 动态添加一个新的标签页 |
|
||||||
|
| `tab_removed(event)` | event: 移除事件对象 | 处理标签被关闭后的清理逻辑,包括内存缓存和自动切换 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 携带数据 |
|
||||||
|
|--------|--------|---------|
|
||||||
|
| `switch` | 当标签页切换完成时触发 | 当前激活的内容控件实例(widget) |
|
||||||
|
| `active`(子控件事件) | 子控件被切换到可见状态时,在其自身上派发 | 无参数,表示该内容已激活 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "main_tab_panel",
|
||||||
|
"widgettype": "TabPanel",
|
||||||
|
"options": {
|
||||||
|
"tab_pos": "top", // 标签位置:可选 'top', 'bottom', 'left', 'right'
|
||||||
|
"tab_long": "100%", // 标签栏宽度/高度设置
|
||||||
|
"css": "custom-tab-style", // 自定义CSS类名
|
||||||
|
"items": [ // 标签页列表
|
||||||
|
{
|
||||||
|
"name": "home",
|
||||||
|
"label": "首页",
|
||||||
|
"icon": "home-icon",
|
||||||
|
"removable": false,
|
||||||
|
"refresh": true,
|
||||||
|
"content": { // 内容部分是一个控件描述JSON
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "home-container"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "欢迎使用Bricks框架!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"text": "点击测试"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "main_tab_panel",
|
||||||
|
"event": "click",
|
||||||
|
"target": "",
|
||||||
|
"script": "console.log('按钮被点击了');",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "settings",
|
||||||
|
"label": "设置",
|
||||||
|
"icon": "setting-icon",
|
||||||
|
"removable": true, // 可关闭标签
|
||||||
|
"refresh": false, // 不刷新,使用缓存
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "/ui/settings.ui", // 从服务器异步加载设置页面
|
||||||
|
"method": "GET",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "main_tab_panel",
|
||||||
|
"event": "switch",
|
||||||
|
"target": "status_bar",
|
||||||
|
"rtdata": {
|
||||||
|
"message": "标签已切换"
|
||||||
|
},
|
||||||
|
"dispatch_event": "update_status"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
- `tab_pos`: 控制标签栏的位置,影响布局方向(水平或垂直)
|
||||||
|
- `items[].content`: 支持直接嵌套控件 JSON 或使用 `urlwidget` 异步加载模块化页面
|
||||||
|
- `removable`: 若为 `true`,标签显示关闭按钮,用户可手动关闭
|
||||||
|
- `refresh`: 若为 `false`,切换时复用已创建的控件实例,提高性能
|
||||||
|
- 使用 `binds` 监听 `switch` 事件,可用于更新状态栏、日志记录等操作
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
✅ **最佳实践建议**:
|
||||||
|
- 对于复杂子页面推荐使用 `urlwidget` 实现按需加载,减少初始渲染负担
|
||||||
|
- 频繁切换的标签建议设置 `refresh: false` 以启用缓存机制
|
||||||
|
- 利用 `switch` 事件做全局状态同步,例如菜单高亮、权限控制等
|
||||||
144
docs/ai/tabular.md
Normal file
144
docs/ai/tabular.md
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# Tabular
|
||||||
|
|
||||||
|
**控件用途**:`Tabular` 是一个用于展示结构化数据的表格型控件,支持行选择、复选框切换、内容展开/折叠等交互功能。适用于列表展示、数据浏览、可编辑表格等场景。
|
||||||
|
|
||||||
|
**类型**:普通控件(继承自 `bricks.DataViewer`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 参数 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `build_other()` | 无 | 异步构建其他组件内容,如获取可编辑字段信息 |
|
||||||
|
| `before_data_handle()` | 无 | 在数据处理前调用,用于初始化表头行 |
|
||||||
|
| `build_header_row()` | 无 | 构建并渲染表头行,添加到 `scrollpanel` 中 |
|
||||||
|
| `build_record_view(record)` | `record`: 数据记录对象 | 根据数据记录创建对应的视图行(支持带详情展开的内容) |
|
||||||
|
| `record_clicked(row, record, event)` | `row`: 行控件, `record`: 数据, `event`: 事件对象 | 处理行点击事件,实现选中状态切换与内容展开 |
|
||||||
|
| `toggle_content(row, flag)` | `row`: 行控件, `flag`: 布尔值 | 控制某一行的详细内容区域显示或隐藏 |
|
||||||
|
| `get_edit_fields()` | 无 | 获取允许编辑的字段列表(排除配置中指定的字段) |
|
||||||
|
| `build_info(record)` | `record`: 数据记录 | 创建单行 `DataRow` 控件,并绑定复选框变化事件 |
|
||||||
|
| `record_check_changed(event)` | `event`: 事件对象 | 当行的复选框状态改变时触发,派发 `row_check_changed` 事件 |
|
||||||
|
| `renew_record_view(form, row)` | `form`: 表单控件, `row`: 被更新的行 | 使用表单数据更新指定行的数据展示 |
|
||||||
|
| `record_event_handle(event_name, record, row, item)` | 各类事件参数 | 捕获并转发行内控件的事件 |
|
||||||
|
| `get_hidefields()` | 无 | 获取当前数据参数中需要作为隐藏字段输出的部分 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 携带数据 | 触发时机 |
|
||||||
|
|-------|----------|---------|
|
||||||
|
| `row_selected` | 当前行对应的 `user_data` 对象 | 用户点击某一行且该行被选中时触发 |
|
||||||
|
| `row_check_changed` | 包含用户数据和复选状态的 `params` 对象 | 行的复选框状态发生变化时触发 |
|
||||||
|
| (转发事件) | 取决于 `event_names` 配置 | 如按钮点击等行内事件通过 `record_event_handle` 转发 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "tabular_user_list",
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
// 继承自 DataViewer 的基础选项
|
||||||
|
"url": "/api/users", // 数据源接口地址
|
||||||
|
"method": "GET", // 请求方式
|
||||||
|
"params": {}, // 请求参数
|
||||||
|
"cheight": 40, // 每行高度
|
||||||
|
"content_view": { // 定义点击后展开的详情内容(可选)
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "姓名: {{name}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "邮箱: {{email}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"row_options": { // 行渲染配置
|
||||||
|
"fields": [ // 字段定义
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"label": "姓名",
|
||||||
|
"uitype": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "age",
|
||||||
|
"label": "年龄",
|
||||||
|
"uitype": "number"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "active",
|
||||||
|
"label": "状态",
|
||||||
|
"uitype": "checkbox"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editexclouded": ["active"] // 不参与编辑的字段(用于编辑模式)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "row_selected",
|
||||||
|
"wid": "tabular_user_list",
|
||||||
|
"event": "row_selected",
|
||||||
|
"target": "detail_panel",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "FormView",
|
||||||
|
"options": {
|
||||||
|
"data": "{{event.params}}",
|
||||||
|
"schema": {
|
||||||
|
"name": { "label": "姓名", "type": "string" },
|
||||||
|
"email": { "label": "邮箱", "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "tabular_user_list",
|
||||||
|
"event": "row_check_changed",
|
||||||
|
"target": "app_state_manager",
|
||||||
|
"dispatch_event": "user_selection_updated",
|
||||||
|
"params": {
|
||||||
|
"selected_user": "{{event.params.user_data}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "tabular_user_list",
|
||||||
|
"event": "click",
|
||||||
|
"target": "logger_service",
|
||||||
|
"method": "logAction",
|
||||||
|
"params": {
|
||||||
|
"action": "view_user",
|
||||||
|
"target_id": "{{event.target.bricks_widget.id}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subwidgets": [] // Tabular 是普通控件,不包含子控件
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释说明:
|
||||||
|
|
||||||
|
- `"content_view"`:定义了每行点击后展开的详细信息面板,使用模板语法 `{{}}` 动态填充数据。
|
||||||
|
- `"editexclouded"`:在编辑场景下排除某些字段(例如只读字段),由 `get_edit_fields()` 方法处理。
|
||||||
|
- `"binds"`:
|
||||||
|
- 第一条绑定监听 `row_selected` 事件,将选中数据传递给另一个容器 `detail_panel` 并渲染为表单;
|
||||||
|
- 第二条绑定将复选变更事件转发为全局事件 `user_selection_updated`;
|
||||||
|
- 第三条调用日志服务的方法记录用户行为。
|
||||||
|
- 所有动态数据均通过 `{{}}` 表达式从运行时上下文中提取,符合 bricks 的数据绑定规范。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> ✅ **提示**:`Tabular` 控件适合与 `DataRow`、`DataViewer` 配合使用,是 Bricks 中实现复杂数据展示的核心控件之一。结合远程加载 (`urlwidget`) 可实现分页、搜索、动态刷新等功能。
|
||||||
111
docs/ai/toolbar.md
Normal file
111
docs/ai/toolbar.md
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# Toolbar
|
||||||
|
|
||||||
|
**用处**:`Toolbar` 是一个用于创建工具栏的容器控件,常用于放置一系列功能按钮(如编辑、保存、删除等),支持横向或纵向布局,并可为每个工具项配置图标、标签、名称和样式。用户点击某个工具按钮时,会触发相应的命令事件。
|
||||||
|
|
||||||
|
**类型**:容器控件,继承自 `bricks.Layout`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `createTool(desc)` | 异步创建一个工具按钮,根据传入的描述对象生成 Button 控件并绑定点击事件 |
|
||||||
|
| `createTools()` | 遍历 `opts.tools` 数组,依次创建所有工具项,并在中间插入间隔元素 |
|
||||||
|
| `add_interval_box()` | 在两个工具项之间添加一个空白间隔(JsWidget),实现视觉分隔 |
|
||||||
|
| `do_handle(tool, event)` | 工具按钮点击后的处理逻辑:高亮当前按钮、派发命令事件和自定义命名事件 |
|
||||||
|
| `remove_item(w, event)` | 移除指定的可移除工具项,触发 `remove` 事件并清理事件监听 |
|
||||||
|
| `add_removable(item)` | 为支持移除的工具项添加一个小的“删除”SVG图标,点击可移除该工具 |
|
||||||
|
| `click(name)` | 模拟点击指定名称的工具按钮,通过名字触发其行为 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发条件 | 参数说明 |
|
||||||
|
|--------|---------|----------|
|
||||||
|
| `command` | 任意工具按钮被点击时触发 | 传递包含工具配置信息的对象,可能包括 `target` 字段 |
|
||||||
|
| `[tool.name]` | 点击具体某个工具按钮时,以该工具的 `name` 值命名的事件被触发 | 数据结构同 `command` 事件 |
|
||||||
|
| `remove` | 当用户点击工具上的删除图标将其移除时触发 | 返回被移除工具的原始配置对象 `tool_opts` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "my_toolbar",
|
||||||
|
"widgettype": "Toolbar",
|
||||||
|
"options": {
|
||||||
|
"orientation": "horizontal", // 可选 'horizontal' 或 'vertical'
|
||||||
|
"interval": "8px", // 工具项之间的间距,默认10px
|
||||||
|
"target": "main_content", // 可选,附加到事件数据中的目标区域标识
|
||||||
|
"css": "custom-toolbar", // 自定义CSS类前缀
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"name": "new_file",
|
||||||
|
"label": "新建文件",
|
||||||
|
"icon": "imgs/new.svg",
|
||||||
|
"css": "btn-new"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "save",
|
||||||
|
"label": "保存",
|
||||||
|
"icon": "imgs/save.svg",
|
||||||
|
"css": "btn-save",
|
||||||
|
"removable": true // 表示这个工具可以被用户手动删除
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "delete",
|
||||||
|
"label": "删除",
|
||||||
|
"icon": "imgs/delete.svg",
|
||||||
|
"css": "btn-delete"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"subwidgets": [], // Toolbar 是容器控件,但通常不直接使用 subwidgets,而是通过 tools 自动生成子控件
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "my_toolbar",
|
||||||
|
"event": "command",
|
||||||
|
"target": "app_handler",
|
||||||
|
"rtdata": {
|
||||||
|
"action": "execute_tool"
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"source": "toolbar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "my_toolbar",
|
||||||
|
"event": "remove",
|
||||||
|
"target": "log_panel",
|
||||||
|
"method": "appendMessage",
|
||||||
|
"params": {
|
||||||
|
"message": "用户移除了一个工具按钮"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "my_toolbar",
|
||||||
|
"event": "save",
|
||||||
|
"target": "none",
|
||||||
|
"script": "async function({ data }) { await fetch('/api/save', { method: 'POST', body: JSON.stringify(data) }); }",
|
||||||
|
"dataparams": {
|
||||||
|
"content": "editor.getValue()"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明**:
|
||||||
|
> - `orientation`: 设置工具栏方向,影响内部使用 `HScrollPanel` 还是 `VScrollPanel`
|
||||||
|
> - `tools`: 定义工具列表,每一项将转换为一个带图标的按钮
|
||||||
|
> - `removable`: 若设为 `true`,则会在该工具上显示一个小的删除图标(SVG),允许用户动态移除
|
||||||
|
> - `binds` 示例展示了三种典型用途:
|
||||||
|
> 1. 监听 `command` 事件统一处理所有工具操作;
|
||||||
|
> 2. 对 `remove` 事件做日志记录;
|
||||||
|
> 3. 对特定工具(如 `save`)执行自定义脚本进行数据提交。
|
||||||
130
docs/ai/tree.md
Normal file
130
docs/ai/tree.md
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
以下是根据你提供的源码和文档规范,为 `Tree` 控件编写的符合 **bricks 控件 JSON 规范** 的控件文档(Markdown 格式):
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tree
|
||||||
|
|
||||||
|
树形结构控件,用于展示层级数据(如文件目录、组织架构等)。支持异步加载子节点、节点选择、自定义节点视图等功能。属于**容器控件**,继承自 `VScrollPanel`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `getValue()` | 获取整个树的数据结构,包含所有节点及其子节点的用户数据。 |
|
||||||
|
| `get_children_data(node)` | 异步从服务器获取指定节点的子节点数据(当配置了 `dataurl` 时调用)。 |
|
||||||
|
| `create_node_children(node, data)` | 根据传入的数据数组创建子节点并添加到指定父节点下。 |
|
||||||
|
| `build_subnode(node, data)` | 创建单个 `TreeNode` 实例并加入容器中。 |
|
||||||
|
| `node_click_handle(node, event)` | 处理节点点击事件,更新选中状态并派发 `node_selected` 事件。 |
|
||||||
|
| `node_selected(node, flag)` | 设置节点的选中样式,并派发 `node_selected` 自定义事件。 |
|
||||||
|
| `append_new_subnode(parentNode, data)` | 向指定父节点追加新子节点,并自动构建 UI。 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发条件 | 携带参数 |
|
||||||
|
|-------|---------|--------|
|
||||||
|
| `node_selected` | 节点被点击选中或取消选中时触发 | 包含节点原始数据及 `selected: true/false` 的对象 |
|
||||||
|
| `check_changed` | 当节点带有复选框且状态改变时触发(需启用 `checkField`) | 节点的用户数据对象 |
|
||||||
|
| `command` | 工具栏按钮点击后触发(如果启用了工具栏) | 工具项的配置信息(name, label 等) |
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "my_tree",
|
||||||
|
"widgettype": "Tree",
|
||||||
|
"options": {
|
||||||
|
// 控件基本属性
|
||||||
|
"width": "100%",
|
||||||
|
"height": "500px",
|
||||||
|
|
||||||
|
// 数据字段映射
|
||||||
|
"idField": "id", // 唯一标识字段
|
||||||
|
"textField": "name", // 显示文本字段
|
||||||
|
"is_leafField": "is_leaf", // 判断是否为叶子节点
|
||||||
|
"typeField": "nodetype", // 节点类型字段(用于图标区分)
|
||||||
|
|
||||||
|
// 行高设置
|
||||||
|
"row_height": "36px",
|
||||||
|
|
||||||
|
// 图标配置(可选)
|
||||||
|
"node_typeicons": {
|
||||||
|
"folder": {
|
||||||
|
"open": "/static/imgs/open-folder.svg",
|
||||||
|
"close": "/static/imgs/close-folder.svg",
|
||||||
|
"leaf": "/static/imgs/file.svg"
|
||||||
|
},
|
||||||
|
"default_type": "folder"
|
||||||
|
},
|
||||||
|
|
||||||
|
// 是否启用复选框功能
|
||||||
|
"checkField": "checked",
|
||||||
|
|
||||||
|
// 静态数据或远程数据 URL(二选一)
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"name": "项目根目录",
|
||||||
|
"is_leaf": false,
|
||||||
|
"nodetype": "folder",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"name": "子模块A",
|
||||||
|
"is_leaf": true,
|
||||||
|
"nodetype": "file"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
/*
|
||||||
|
或者使用远程数据:
|
||||||
|
"dataurl": "/api/tree/nodes",
|
||||||
|
"method": "GET",
|
||||||
|
"params": {
|
||||||
|
"appid": "123"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
|
||||||
|
// 子控件(无,因为 Tree 自主管理子节点)
|
||||||
|
"subwidgets": [],
|
||||||
|
|
||||||
|
// 事件绑定
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "my_tree",
|
||||||
|
"event": "node_selected",
|
||||||
|
"target": "output_panel",
|
||||||
|
"rtdata": {
|
||||||
|
"action": "show_node_info"
|
||||||
|
},
|
||||||
|
"datawidget": "my_tree",
|
||||||
|
"datamethod": "getValue",
|
||||||
|
"dataparams": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "my_tree",
|
||||||
|
"event": "check_changed",
|
||||||
|
"target": "Popup",
|
||||||
|
"script": "console.log('节点勾选变化:', params); notifyUser(params.name + ' 状态已更新');",
|
||||||
|
"params": {
|
||||||
|
"source": "tree_check"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
>
|
||||||
|
> - `widgettype`: 必须是已在 `bricks.Factory.register` 中注册的名称,此处为 `"Tree"`。
|
||||||
|
> - `options.data`: 提供初始静态数据;若使用 `dataurl`,则会在运行时动态加载。
|
||||||
|
> - `checkField`: 开启复选框功能,每个节点数据中应包含该字段(如 `"checked": true`)。
|
||||||
|
> - `binds` 示例展示了如何监听节点选中与复选变化,并执行脚本或传递数据给其他组件。
|
||||||
|
> - 所有图标路径建议通过 `bricks_resource()` 函数处理以确保资源定位正确。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 📌 **提示**:若需编辑功能(增删改),请使用继承自 `Tree` 的 `EditableTree` 或在 `options` 中提供 `editable` 配置及对应的 `add_url`, `delete_url`, `update_url` 接口地址。
|
||||||
98
docs/ai/vadtext.md
Normal file
98
docs/ai/vadtext.md
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# VadText
|
||||||
|
|
||||||
|
用于实现语音识别(ASR)功能的复合控件,结合了麦克风音频采集、端点检测(VAD)、音频播放和文本显示功能。用户点击按钮开始录音,当检测到语音结束时自动发送音频至后端进行识别,并将识别结果实时追加显示在文本区域中。
|
||||||
|
|
||||||
|
**类型:** 普通控件(继承自 `bricks.VBox`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `start()`
|
||||||
|
启动语音识别流程,初始化 MicVAD 实例并开始监听麦克风输入。
|
||||||
|
|
||||||
|
- `_start()` *(async)*
|
||||||
|
异步内部方法,创建 `MicVAD` 实例并设置 `onSpeechEnd` 回调,在检测到语音结束后触发 `audio_ready` 事件。
|
||||||
|
|
||||||
|
- `stop()`
|
||||||
|
停止当前的语音识别过程,暂停 VAD 并清理状态。
|
||||||
|
|
||||||
|
- `_stop()` *(async)*
|
||||||
|
异步停止逻辑,调用 VAD 的 `pause()` 方法,清除引用,并在有文本内容时派发 `changed` 事件。
|
||||||
|
|
||||||
|
- `toggle_status()`
|
||||||
|
切换录音状态:若正在录音则停止,否则启动录音。
|
||||||
|
|
||||||
|
- `handle_audio(audio)` *(async)*
|
||||||
|
处理 VAD 捕获的音频数据:
|
||||||
|
- 将 `Float32Array` 格式的音频转换为 WAV ArrayBuffer
|
||||||
|
- 编码为 Base64 数据 URL 并在内嵌播放器中播放
|
||||||
|
- 发送 Base64 音频到指定 URL 进行 ASR 识别
|
||||||
|
- 更新识别文本并触发界面刷新
|
||||||
|
|
||||||
|
- `arrayBufferToBase64(buffer)`
|
||||||
|
将 ArrayBuffer 转换为 Base64 字符串,用于构建 `data:` URL。
|
||||||
|
|
||||||
|
- `getValue()`
|
||||||
|
获取当前控件的输出值,返回一个对象,键为 `this.name`,值为累计识别文本。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `audio_ready`
|
||||||
|
当 VAD 检测到一段语音结束并捕获音频数据后触发,携带原始音频数据(`Float32Array`),用于后续处理。
|
||||||
|
|
||||||
|
- `changed`
|
||||||
|
当一次录音完成且识别出文本内容不为空时触发,携带当前完整识别结果(通过 `getValue()` 获取)。通常用于表单提交或数据同步。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "vad_text_widget",
|
||||||
|
"widgettype": "VadText",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/asr/recognize", // ASR服务接口地址
|
||||||
|
"model": "whisper-small", // 可选模型参数
|
||||||
|
"name": "user_speech" // 表单字段名,getValue时使用
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "vad_text_widget",
|
||||||
|
"event": "changed",
|
||||||
|
"target": "form_container",
|
||||||
|
"dispatch_event": "field_changed",
|
||||||
|
"params": {
|
||||||
|
"source": "vad_text_widget"
|
||||||
|
},
|
||||||
|
"rtdata": {
|
||||||
|
"component": "asr_input"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "vad_text_widget",
|
||||||
|
"event": "audio_ready",
|
||||||
|
"target": "status_label",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "正在识别..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `widgettype: "VadText"` 是注册过的自定义控件。
|
||||||
|
> - `options.url` 是必须项,指向后端提供 ASR 功能的 API 接口。
|
||||||
|
> - `binds` 中第一个绑定监听 `changed` 事件,向父容器派发 `field_changed` 自定义事件,可用于通知表单更新。
|
||||||
|
> - 第二个绑定在 `audio_ready` 触发时替换某个标签控件的内容,提示“正在识别”,增强用户体验。
|
||||||
|
> - 此控件适合嵌入表单、语音助手、语音输入等场景。
|
||||||
174
docs/ai/videoplayer.md
Normal file
174
docs/ai/videoplayer.md
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
# VideoPlayer
|
||||||
|
|
||||||
|
用于播放视频内容,支持多种格式(MP4、HLS `.m3u8`、DASH `.mpd`),具备完整的播放控制功能。类型:普通控件,继承自 `VBox`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`loadVideo(src)`**
|
||||||
|
加载指定的视频源,自动判断是 MP4、HLS 还是 DASH 格式,并初始化对应的播放器(原生 `<video>`、Hls.js 或 dash.js)。
|
||||||
|
|
||||||
|
- **`init()`**
|
||||||
|
初始化播放器,在 DOM 挂载后调用,加载视频并绑定事件。
|
||||||
|
|
||||||
|
- **`destroy()`**
|
||||||
|
销毁当前播放器实例,释放 Hls 或 dash.js 资源,清空视频源。
|
||||||
|
|
||||||
|
- **`bindEvents()`**
|
||||||
|
绑定所有 UI 控件与视频元素的交互事件,如播放/暂停、音量、全屏等。
|
||||||
|
|
||||||
|
- **`updateUI()`**
|
||||||
|
更新播放器界面状态(播放按钮、静音、进度条时间等)。
|
||||||
|
|
||||||
|
- **`show_controls()` / `hide_controls()`**
|
||||||
|
显示或隐藏控制栏,点击视频时显示,4秒无操作后自动隐藏。
|
||||||
|
|
||||||
|
- **`setValue(url)`**
|
||||||
|
动态设置播放地址并重新加载视频(可用于切换频道或视频源)。
|
||||||
|
|
||||||
|
- **`set_url(newUrl)`**
|
||||||
|
外部调用接口,用于更新播放地址(等价于 `setValue` 的快捷方式)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`play_ok`**
|
||||||
|
当视频成功开始播放时触发(内部通过监听 `playing` 事件派发),可用于上报播放成功日志。
|
||||||
|
|
||||||
|
- **`play_failed`**
|
||||||
|
视频加载失败或无法播放时触发,可用于错误上报。
|
||||||
|
|
||||||
|
> 注:这两个事件由 `Iptv` 控件监听并用于上报播放状态。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "my_video_player",
|
||||||
|
"widgettype": "VideoPlayer",
|
||||||
|
"options": {
|
||||||
|
"url": "https://example.com/video/stream.m3u8", // 支持 .m3u8 (HLS), .mpd (DASH), .mp4 等
|
||||||
|
"autoplay": true // 是否自动播放
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "my_video_player",
|
||||||
|
"event": "play_ok",
|
||||||
|
"target": "logger_widget",
|
||||||
|
"dispatch_event": "log_message",
|
||||||
|
"params": {
|
||||||
|
"message": "视频播放成功"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "my_video_player",
|
||||||
|
"event": "play_failed",
|
||||||
|
"target": "alert_popup",
|
||||||
|
"dispatch_event": "show",
|
||||||
|
"params": {
|
||||||
|
"title": "播放失败",
|
||||||
|
"content": "无法加载该视频流,请检查网络或资源地址。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "control_btn_playpause",
|
||||||
|
"event": "click",
|
||||||
|
"target": "my_video_player",
|
||||||
|
"method": "setValue",
|
||||||
|
"params": {
|
||||||
|
"url": "https://another-example.com/live/stream.mpd" // 切换为 DASH 流
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - 使用 `VideoPlayer` 播放 HLS/DASH/MP4 视频流;
|
||||||
|
> - 支持通过事件绑定实现播放成功/失败的日志记录和提示;
|
||||||
|
> - 可通过外部按钮点击动态调用 `setValue` 方法更换视频源;
|
||||||
|
> - 自动检测格式并使用 Hls.js 或 dash.js 渲染(需提前引入对应库);
|
||||||
|
> - 包含播放、暂停、音量、倍速、音轨选择、全屏等功能;
|
||||||
|
> - 控制栏在无操作 4 秒后自动隐藏,点击画面可重新显示。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Iptv
|
||||||
|
|
||||||
|
专为 IPTV 场景设计的容器控件,封装了用户认证、频道信息获取与视频播放逻辑。类型:容器控件,继承自 `VBox`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`build_subwidgets()`**
|
||||||
|
异步构建子控件:首先请求服务器获取用户频道数据,然后创建 `VideoPlayer` 和标题 `Text` 控件并添加到界面中。
|
||||||
|
|
||||||
|
- **`report_play_ok()`**
|
||||||
|
当播放成功时向服务器上报“播放成功”事件(例如用于统计收视率)。
|
||||||
|
|
||||||
|
- **`report_play_failed()`**
|
||||||
|
当播放失败时向服务器上报“播放失败”事件。
|
||||||
|
|
||||||
|
- **`setValue(data)`**
|
||||||
|
外部传入新的频道数据,动态更新当前播放内容(包括标题和视频地址)。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- **`play_ok`**
|
||||||
|
被 `VideoPlayer` 子控件触发,表示播放已开始,本控件会进一步上报给服务端。
|
||||||
|
|
||||||
|
- **`play_failed`**
|
||||||
|
播放异常时触发,用于错误追踪和上报。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "iptv_container",
|
||||||
|
"widgettype": "Iptv",
|
||||||
|
"options": {
|
||||||
|
"iptv_data_url": "/api/iptv/channel", // 获取频道信息的接口
|
||||||
|
"playok_url": "/api/report/playok", // 上报播放成功的 URL
|
||||||
|
"playfailed_url": "/api/report/playfailed" // 上报播放失败的 URL
|
||||||
|
},
|
||||||
|
"subwidgets": [], // 动态生成,无需手动填写
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"wid": "channel_list_item",
|
||||||
|
"event": "click",
|
||||||
|
"target": "iptv_container",
|
||||||
|
"action": "replace",
|
||||||
|
"options": {
|
||||||
|
"url": "/api/iptv/channel",
|
||||||
|
"params": {
|
||||||
|
"channel_id": "{channel_id}" // 来自动态数据
|
||||||
|
},
|
||||||
|
"method": "GET"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_change_channel",
|
||||||
|
"event": "click",
|
||||||
|
"target": "iptv_container",
|
||||||
|
"method": "setValue",
|
||||||
|
"dataparams": {
|
||||||
|
"tv_name": "CCTV-5 体育频道",
|
||||||
|
"url": "https://live.cctv.com/cctv5.m3u8",
|
||||||
|
"id": "cctv5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ✅ **注释说明:**
|
||||||
|
> - `Iptv` 是一个高级封装控件,适用于需要鉴权、播放上报的直播场景;
|
||||||
|
> - 初始化时会从 `iptv_data_url` 获取频道信息(包含 `url`, `tv_name`, `id` 等字段);
|
||||||
|
> - 成功播放时自动调用 `playok_url` 上报设备 ID 和频道 ID;
|
||||||
|
> - 播放失败也会尝试上报错误;
|
||||||
|
> - 支持通过 `setValue` 方法直接切换频道内容;
|
||||||
|
> - 可结合列表项点击动态加载不同频道(使用 `urlwidget` 绑定);
|
||||||
|
> - 实际渲染结构为:顶部标题 + 下方 VideoPlayer;
|
||||||
|
> - 需确保页面已引入 Hls.js 或 dash.js 库以支持流媒体协议。
|
||||||
163
docs/ai/websocket.md
Normal file
163
docs/ai/websocket.md
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
# WebSocket
|
||||||
|
|
||||||
|
WebSocket 控件是一个**容器控件**,继承自 `VBox`,用于在 Bricks.js 框架中建立与后端的 WebSocket 长连接。它支持文本、音频(base64 编码)、视频(base64 编码)等类型的数据双向通信,并能根据消息类型自动派发对应的事件。适用于实时通信场景,如语音识别、视频流传输、聊天系统等。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- **`send_text(text)`**
|
||||||
|
发送文本类型的消息到服务器。
|
||||||
|
参数:`text`(字符串)
|
||||||
|
|
||||||
|
- **`send_base64_video(b64video)`**
|
||||||
|
发送 base64 编码的视频数据到服务器。
|
||||||
|
参数:`b64video`(字符串,base64 视频数据)
|
||||||
|
|
||||||
|
- **`send_base64_audio(b64audio)`**
|
||||||
|
发送 base64 编码的音频数据到服务器。
|
||||||
|
参数:`b64audio`(字符串,base64 音频数据)
|
||||||
|
|
||||||
|
- **`send_typedata(type, data)`**
|
||||||
|
发送指定类型和内容的数据包。
|
||||||
|
参数:
|
||||||
|
- `type`:自定义消息类型(如 `"command"`)
|
||||||
|
- `data`:任意数据对象或字符串
|
||||||
|
|
||||||
|
- **`send(d)`**
|
||||||
|
将一个对象格式化为 JSON 并通过 WebSocket 发送。
|
||||||
|
参数:`d`(对象,结构为 `{ type: "...", data: ... }`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
WebSocket 控件会在特定时机派发以下事件,可通过 `binds` 进行监听:
|
||||||
|
|
||||||
|
- **`onopen`**
|
||||||
|
WebSocket 连接成功建立时触发。
|
||||||
|
|
||||||
|
- **`onclose`**
|
||||||
|
WebSocket 连接关闭时触发。
|
||||||
|
|
||||||
|
- **`onerror`**
|
||||||
|
WebSocket 发生错误时触发。
|
||||||
|
|
||||||
|
- **`ontext`**
|
||||||
|
收到类型为 `text` 的消息时触发(对应 `d.type === "text"`)。
|
||||||
|
|
||||||
|
- **`onbase64audio`**
|
||||||
|
收到 base64 编码的音频数据时触发。
|
||||||
|
|
||||||
|
- **`onbase64video`**
|
||||||
|
收到 base64 编码的视频数据时触发。
|
||||||
|
|
||||||
|
- **其他自定义类型事件**
|
||||||
|
若收到的消息类型为 `custom`,会自动派发名为 `oncustom` 的事件。
|
||||||
|
|
||||||
|
> 注:所有来自服务端的消息需为 JSON 格式,结构为 `{ type: "xxx", data: ... }`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "ws_conn_01",
|
||||||
|
"widgettype": "WebSocket",
|
||||||
|
"options": {
|
||||||
|
"ws_url": "wss://example.com/api/ws", // WebSocket 服务器地址
|
||||||
|
"with_session": true // 是否携带会话信息(如 token)
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "btn_start",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"label": "开始连接"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "log_area",
|
||||||
|
"widgettype": "TextArea",
|
||||||
|
"options": {
|
||||||
|
"readonly": true,
|
||||||
|
"placeholder": "日志输出区域"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_start",
|
||||||
|
"event": "click",
|
||||||
|
"target": "ws_conn_01",
|
||||||
|
"method": "send_text",
|
||||||
|
"params": {
|
||||||
|
"text": "Hello from client!"
|
||||||
|
},
|
||||||
|
"conform": {
|
||||||
|
"title": "确认发送",
|
||||||
|
"message": "确定要发送消息吗?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "ws_conn_01",
|
||||||
|
"event": "onopen",
|
||||||
|
"target": "log_area",
|
||||||
|
"dispatch_event": "setValue",
|
||||||
|
"rtdata": {
|
||||||
|
"value": "✅ WebSocket 已连接\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "ws_conn_01",
|
||||||
|
"event": "ontext",
|
||||||
|
"target": "log_area",
|
||||||
|
"script": "async function({ target, params }) { const current = target.getValue(); target.setValue(current + '[TEXT] ' + (params || '') + '\\n'); }",
|
||||||
|
"datawidget": "ws_conn_01",
|
||||||
|
"datamethod": "getValue" // 实际上 ontext 的数据由事件参数传入,此处仅为示意
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "ws_conn_01",
|
||||||
|
"event": "onbase64video",
|
||||||
|
"target": "Popup",
|
||||||
|
"script": "async function({ params }) { console.log('播放视频:', params); /* 可在此处调用媒体播放控件 */ }",
|
||||||
|
"dataparams": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "bricks",
|
||||||
|
"wid": "ws_conn_01",
|
||||||
|
"event": "onerror",
|
||||||
|
"target": "Popup",
|
||||||
|
"mode": "replace",
|
||||||
|
"options": {
|
||||||
|
"widgettype": "MessageBox",
|
||||||
|
"options": {
|
||||||
|
"title": "WebSocket 错误",
|
||||||
|
"content": "连接出现异常,请检查网络或服务状态。",
|
||||||
|
"type": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释说明
|
||||||
|
|
||||||
|
- `widgettype: "WebSocket"` 表示这是一个 WebSocket 容器控件。
|
||||||
|
- `options.ws_url` 是必须项,指定 WebSocket 服务地址。
|
||||||
|
- `with_session: true` 会尝试从 `bricks.app.get_session()` 获取会话信息并作为协议参数传递(具体实现取决于应用逻辑)。
|
||||||
|
- 子控件包括按钮和文本区域,用于用户交互和日志展示。
|
||||||
|
- `binds` 中定义了多种行为:
|
||||||
|
- 点击按钮时向 WebSocket 发送文本;
|
||||||
|
- 连接成功时更新日志;
|
||||||
|
- 接收到文本消息时追加显示;
|
||||||
|
- 接收到视频数据时可通过脚本处理(如播放);
|
||||||
|
- 出错时弹出提示框。
|
||||||
|
|
||||||
|
> ⚠️ 注意:实际使用中需确保服务端返回的消息符合 `{ type: "...", data: ... }` 结构,否则可能无法正确触发事件。
|
||||||
144
docs/ai/webspeech.md
Normal file
144
docs/ai/webspeech.md
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# WebTTS
|
||||||
|
|
||||||
|
用于实现网页端的文本转语音(Text-to-Speech)功能,基于浏览器原生 `SpeechSynthesis` API。该控件为**普通控件**,继承自 `VBox`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `speak(text: String)`
|
||||||
|
开始朗读指定的文本内容。若浏览器不支持语音合成功能,则输出错误日志。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
无自定义事件派发。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "tts_widget",
|
||||||
|
"widgettype": "WebTTS",
|
||||||
|
"options": {
|
||||||
|
// 可选配置项(当前无特定 options)
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method", // 调用方法动作
|
||||||
|
"wid": "btn_speak", // 触发组件ID:一个按钮
|
||||||
|
"event": "click", // 监听点击事件
|
||||||
|
"target": "tts_widget", // 目标控件ID
|
||||||
|
"method": "speak", // 调用的方法名
|
||||||
|
"dataparams": {
|
||||||
|
"text": "欢迎使用Bricks框架的WebTTS功能"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "input_text", // 输入框控件ID
|
||||||
|
"event": "change", // 值变化时触发
|
||||||
|
"target": "tts_widget",
|
||||||
|
"method": "speak",
|
||||||
|
"datawidget": "input_text", // 从input_text控件获取数据
|
||||||
|
"datamethod": "getValue" // 调用其getValue方法获取输入值
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - 此控件通过调用 `speak()` 方法播放语音。
|
||||||
|
> - 示例中绑定了两个事件:
|
||||||
|
> 1. 点击按钮时,朗读固定欢迎语;
|
||||||
|
> 2. 当输入框内容改变时,自动朗读输入的内容。
|
||||||
|
> - 需确保运行环境支持 `window.speechSynthesis`,否则会打印不支持提示。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# WebASR
|
||||||
|
|
||||||
|
实现语音识别(Automatic Speech Recognition, ASR)功能,基于浏览器的 `SpeechRecognition` 接口。该控件为**普通控件**,继承自 `VBox`。
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
- `start_recording()`
|
||||||
|
启动麦克风录音并开始语音识别,识别结果通过事件派发。
|
||||||
|
|
||||||
|
- `stop_recording()`
|
||||||
|
停止语音识别过程。
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
- `asr_result`
|
||||||
|
当语音识别完成并获得结果时触发,携带参数 `{ content: string }`,表示识别出的文本内容。
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "asr_widget",
|
||||||
|
"widgettype": "WebASR",
|
||||||
|
"options": {},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "btn_start_asr",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"label": "开始录音"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "btn_stop_asr",
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"label": "停止录音"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "result_display",
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "等待识别结果..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_start_asr",
|
||||||
|
"event": "click",
|
||||||
|
"target": "asr_widget",
|
||||||
|
"method": "start_recording"
|
||||||
|
// 开始语音识别
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_stop_asr",
|
||||||
|
"event": "click",
|
||||||
|
"target": "asr_widget",
|
||||||
|
"method": "stop_recording"
|
||||||
|
// 停止语音识别
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "asr_widget",
|
||||||
|
"event": "asr_result", // 监听控件自身派发的 asr_result 事件
|
||||||
|
"target": "result_display", // 目标是显示结果的 Label 控件
|
||||||
|
"dispatch_event": "setValue", // 派发 setValue 事件来更新文本
|
||||||
|
"params": {
|
||||||
|
"value": "{content}" // 使用事件携带的数据字段 content 更新显示
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注释说明:**
|
||||||
|
> - `WebASR` 控件依赖于浏览器是否支持 `SpeechRecognition`。
|
||||||
|
> - 用户点击“开始录音”按钮后,激活麦克风进行语音识别。
|
||||||
|
> - 识别完成后,控件派发 `asr_result` 事件,携带识别文本。
|
||||||
|
> - 利用 `event` 类型绑定将识别结果动态更新到 `result_display` 标签中。
|
||||||
|
> - “停止录音”按钮可手动结束识别流程。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 💡 **提示:**
|
||||||
|
> 在实际使用中,请确保页面在 HTTPS 环境下运行,因为大多数浏览器对非安全上下文下的麦克风和语音合成功能进行了限制。
|
||||||
252
docs/ai/widget.md
Normal file
252
docs/ai/widget.md
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
# Text
|
||||||
|
用处:用于在界面上显示静态文本内容,支持国际化、文本对齐和样式配置
|
||||||
|
类型:普通控件,继承自`TextBase`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
| 方法名 | 描述 |
|
||||||
|
|----------------|----------------------------------------------------------------------|
|
||||||
|
| `set_text(text)` | 设置控件显示的文本内容 |
|
||||||
|
| `set_otext(otxt)` | 设置国际化文本键,自动根据当前语言翻译并显示 |
|
||||||
|
| `set_style(k, v)` | 设置控件的CSS样式属性 |
|
||||||
|
| `set_css(css)` | 为控件添加CSS类 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件(继承自`JsWidget`的基础事件如`click`、`mousemove`等可用)
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "text_demo",
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "Hello, Bricks!", // 直接设置显示文本
|
||||||
|
"halign": "center", // 水平居中对齐
|
||||||
|
"valign": "middle", // 垂直居中对齐
|
||||||
|
"css": "my-text-style", // 自定义CSS类
|
||||||
|
"bgcolor": "#f0f0f0" // 背景颜色
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "text_demo",
|
||||||
|
"event": "click",
|
||||||
|
"script": "console.log('Text clicked!')" // 点击时执行脚本
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# KeyinText
|
||||||
|
用处:允许用户通过键盘输入和编辑文本内容,并在文本变化时触发事件通知
|
||||||
|
类型:普通控件,继承自`Text`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
| 方法名 | 描述 |
|
||||||
|
|----------------------|----------------------------------------------------------------------|
|
||||||
|
| `key_down_action(event)` | 处理键盘输入事件,支持删除、退格和字符输入 |
|
||||||
|
| `dispatch_changed()` | 当文本内容变化时触发`changed`事件 |
|
||||||
|
| `set_text(text)` | 设置控件显示的文本内容 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
| 事件名 | 描述 |
|
||||||
|
|----------|----------------------------------------------------------------------|
|
||||||
|
| `changed` | 当文本内容发生变化时触发,携带当前文本数据 |
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "keyin_demo",
|
||||||
|
"widgettype": "KeyinText",
|
||||||
|
"options": {
|
||||||
|
"text": "Enter text here...", // 初始文本
|
||||||
|
"name": "input_data", // 事件数据中的键名
|
||||||
|
"halign": "left", // 左对齐
|
||||||
|
"width": "200px" // 宽度
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "keyin_demo",
|
||||||
|
"event": "changed",
|
||||||
|
"script": "console.log('Input changed:', params)" // 文本变化时打印数据
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Title1
|
||||||
|
用处:用于显示一级标题文本,字体较大且加粗
|
||||||
|
类型:普通控件,继承自`TextBase`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
同`Text`控件
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "title1_demo",
|
||||||
|
"widgettype": "Title1",
|
||||||
|
"options": {
|
||||||
|
"text": "Main Title", // 标题文本
|
||||||
|
"halign": "center" // 居中对齐
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Title2
|
||||||
|
用处:用于显示二级标题文本,字体大小略小于Title1且加粗
|
||||||
|
类型:普通控件,继承自`TextBase`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
同`Text`控件
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "title2_demo",
|
||||||
|
"widgettype": "Title2",
|
||||||
|
"options": {
|
||||||
|
"text": "Section Title", // 标题文本
|
||||||
|
"halign": "left" // 左对齐
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Title3
|
||||||
|
用处:用于显示三级标题文本,字体大小略小于Title2且加粗
|
||||||
|
类型:普通控件,继承自`TextBase`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
同`Text`控件
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "title3_demo",
|
||||||
|
"widgettype": "Title3",
|
||||||
|
"options": {
|
||||||
|
"text": "Subsection Title", // 标题文本
|
||||||
|
"css": "custom-title" // 自定义样式
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Title4
|
||||||
|
用处:用于显示四级标题文本,字体大小略小于Title3且加粗
|
||||||
|
类型:普通控件,继承自`TextBase`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
同`Text`控件
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "title4_demo",
|
||||||
|
"widgettype": "Title4",
|
||||||
|
"options": {
|
||||||
|
"otext": "i18n_title", // 国际化文本键
|
||||||
|
"i18n": true // 启用国际化
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Title5
|
||||||
|
用处:用于显示五级标题文本,字体大小略小于Title4且加粗
|
||||||
|
类型:普通控件,继承自`TextBase`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
同`Text`控件
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "title5_demo",
|
||||||
|
"widgettype": "Title5",
|
||||||
|
"options": {
|
||||||
|
"text": "Small Title", // 标题文本
|
||||||
|
"color": "#333333" // 文本颜色
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Title6
|
||||||
|
用处:用于显示六级标题文本,字体大小略小于Title5且加粗
|
||||||
|
类型:普通控件,继承自`TextBase`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
同`Text`控件
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "title6_demo",
|
||||||
|
"widgettype": "Title6",
|
||||||
|
"options": {
|
||||||
|
"text": "Caption", // 标题文本
|
||||||
|
"bgcolor": "#ffffff" // 背景颜色
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Tooltip
|
||||||
|
用处:用于在用户与目标控件交互时显示提示信息,支持自动隐藏和位置调整
|
||||||
|
类型:普通控件,继承自`Text`
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
| 方法名 | 描述 |
|
||||||
|
|------------------|----------------------------------------------------------------------|
|
||||||
|
| `show(otext, event)` | 显示提示信息,接收国际化文本键和触发事件以定位 |
|
||||||
|
| `hide()` | 隐藏提示信息 |
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
无自定义事件(通常与目标控件的鼠标事件联动使用)
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "tooltip_target",
|
||||||
|
"widgettype": "Button", // 假设存在Button控件
|
||||||
|
"options": {
|
||||||
|
"text": "Hover me", // 按钮文本
|
||||||
|
"tip": "This is a button" // Tooltip提示文本
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"id": "tooltip_demo",
|
||||||
|
"widgettype": "Tooltip",
|
||||||
|
"options": {
|
||||||
|
"rate": 0.8, // 文本缩放比例
|
||||||
|
"text": "Default tooltip" // 默认提示文本
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注意:Tooltip通常通过目标控件的`tip`属性自动关联,无需单独定义。上述例子展示了手动创建Tooltip的方式。
|
||||||
207
docs/ai/widgets.md
Normal file
207
docs/ai/widgets.md
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
# bricks控件
|
||||||
|
bricks内置许多的显示控件,所有显示控件都继承自JsWidget,容器控件Layout就继承自JsWidget,其他的容器HBox, VBox继承自Layout
|
||||||
|
|
||||||
|
## 基础控件
|
||||||
|
* [Form](form.md):输入表单控件
|
||||||
|
自动根据options中的fields定义构造表单,目前支持的数据类型有:
|
||||||
|
** 'str' 对应的控件为: bricks.UiStr
|
||||||
|
** 'hide' 对应的控件为: bricks.UiHide
|
||||||
|
** 'tel' 对应的控件为: bricks.UiTel
|
||||||
|
** 'date' 对应的控件为: bricks.UiDate
|
||||||
|
** 'int' 对应的控件为: bricks.UiInt
|
||||||
|
** 'float' 对应的控件为: bricks.UiFloat
|
||||||
|
** 'check' 对应的控件为: bricks.UiCheck
|
||||||
|
** 'checkbox' 对应的控件为: bricks.UiCheckBox
|
||||||
|
** 'email' 对应的控件为: bricks.UiEmail
|
||||||
|
** 'file' 对应的控件为: bricks.UiFile
|
||||||
|
** 'image' 对应的控件为: bricks.UiImage
|
||||||
|
** 'code' 对应的控件为: bricks.UiCode
|
||||||
|
** 'text' 对应的控件为: bricks.UiText
|
||||||
|
** 'password' 对应的控件为: bricks.UiPassword
|
||||||
|
** 'audio' 对应的控件为: bricks.UiAudio
|
||||||
|
** 'video' 对应的控件为: bricks.UiVideo
|
||||||
|
上述控件都在[输入定义](inout.js)
|
||||||
|
* [Accordion](accordion.md) bricks.Accordion
|
||||||
|
手风琴控件,支持多个标题,内容组成的控件,内容和展开和折叠
|
||||||
|
* [AudioPlayer](audio.md) bricks.AudioPlayer
|
||||||
|
音频播放控件
|
||||||
|
|
||||||
|
* [ChartBar](bar.md) bricks.ChartBar
|
||||||
|
将后台数据显示为条形图表
|
||||||
|
* [Button](button.md) bricks.Button
|
||||||
|
按钮控件
|
||||||
|
|
||||||
|
* [Cols](cols.md) bricks.Cols
|
||||||
|
列式排列控件,可动态填满父控件的宽度
|
||||||
|
* [Conform](conform.md) bricks.Conform
|
||||||
|
确认控件,弹出窗口显示内容,并要求用户确认
|
||||||
|
|
||||||
|
* [Countdown](countdown.md) bricks.Countdown
|
||||||
|
时间倒计时控件,显示从还剩下的时间
|
||||||
|
* [TimePassed](countdown.md) bricks.TimePassed
|
||||||
|
时间消耗控件,显示从开始计时开始所消耗的时间
|
||||||
|
* [DataGrid](datagrid.md) bricks.DataGrid
|
||||||
|
数据表格控件
|
||||||
|
* [DataRow](datarow.md) bricks.DataRow
|
||||||
|
数据行控件
|
||||||
|
* [DataViewer](dataviewer.md) bricks.DataViewer
|
||||||
|
数据显示控件,DynamicColumn控件的后代控件
|
||||||
|
* [DOCXviewer](docxviewer.md) bricks.DOCXviewer
|
||||||
|
docx文件显示控件
|
||||||
|
* [EXCELviewer](docxviewer.md) bricks.EXCELviewer
|
||||||
|
excel文件显示控件
|
||||||
|
* [PDFviewer](accordion.md) bricks.PDFviewer
|
||||||
|
pdf显示控件
|
||||||
|
* [DynamicAccordion](dynamicaccordion.md) bricks.DynamicAccordion
|
||||||
|
动态手风琴控件
|
||||||
|
* [IconBar](floaticonbar.md) bricks.IconBar
|
||||||
|
图标条控件
|
||||||
|
* [IconTextBar](floaticonbar.md) bricks.IconTextBar
|
||||||
|
图标文本条控件
|
||||||
|
* [FloatIconBar](floaticonbar.md) bricks.FloatIconBar
|
||||||
|
浮动图标条,平时显示一个标识图标,点击此标识图标后显示图标条
|
||||||
|
* [FloatIconTextBar](floaticonbar.md) bricks.FloatIconTextBar
|
||||||
|
浮动图标正文条,平时显示一个标识图标,点击此图标后显示图标正文条
|
||||||
|
|
||||||
|
* [Html](html.md) bricks.Html
|
||||||
|
HTML控件,直接显示html内容
|
||||||
|
* [IconbarPage](iconbarpage.md) bricks.IconbarPage
|
||||||
|
图标条页控件,显示图标条,不同的图标点击后显示图标对应的内容
|
||||||
|
|
||||||
|
* [NewWindow](iframe.md) bricks.NewWindow
|
||||||
|
新浏览器页签或窗口控件,浏览器创建新的窗口或页签显示url的内容
|
||||||
|
* [Iframe](iframe.md) bricks.Iframe
|
||||||
|
Iframe控件,用于显示外部网站内容
|
||||||
|
* [Image](image.md) bricks.Image
|
||||||
|
图像控件
|
||||||
|
* [StatedIcon](image.md) bricks.StatedIcon
|
||||||
|
多站台图标,点击后状态改变,支持多个状态,并发出状态改变事件
|
||||||
|
* [Icon](image.md) bricks.Icon
|
||||||
|
图标控件,支持多种图像格式url
|
||||||
|
* [BlankIcon](image.md) bricks.BlankIcon
|
||||||
|
空白图标占位控件
|
||||||
|
|
||||||
|
* [ChartLine](line.md) bricks.ChartLine
|
||||||
|
* [LlmIO](llm.md) bricks.LlmIO
|
||||||
|
* [LlmOut](llm.md) bricks.LlmOut
|
||||||
|
* [MarkdownViewer](markdownviewer.md) bricks.MarkdownViewer
|
||||||
|
* [MdWidget](markdownviewer.md) bricks.MdWidget
|
||||||
|
* [Menu](menu.md) bricks.Menu
|
||||||
|
* [Message](message.md) bricks.Message
|
||||||
|
* [Error](message.md) bricks.Error
|
||||||
|
|
||||||
|
* [MultipleStateImage](multiple_state_image.md) bricks.MultipleStateImage
|
||||||
|
多状态图像控件
|
||||||
|
* [PeriodDays](period.md) bricks.PeriodDays
|
||||||
|
日期期间控件,自动计算时间段的起始日期
|
||||||
|
* [ChartPie](pie.md) bricks.ChartPie
|
||||||
|
饼图控件,基于echrts
|
||||||
|
* [ProgressBar](progressbar.md) bricks.ProgressBar
|
||||||
|
进度条控件
|
||||||
|
* [SysCamera](recorder.md) bricks.SysCamera
|
||||||
|
照相控件,可拍摄照片
|
||||||
|
* [WidgetRecorder](recorder.md) bricks.WidgetRecorder
|
||||||
|
控件视频录制控件,可录制浏览器播放的视频
|
||||||
|
* [SysAudioRecorder](recorder.md) bricks.SysAudioRecorder
|
||||||
|
浏览器音频录制控件,用来录制音频
|
||||||
|
* [SysVideoRecorder](recorder.md) bricks.SysVideoRecorder
|
||||||
|
浏览器视频录制控件,用来录制视频
|
||||||
|
* [Running](running.md) bricks.Running
|
||||||
|
运行图标控件,modal模式显示正在运行,相关控件不可操作,需要在完成 任务后dismiss它
|
||||||
|
* [Splitter](splitter.md) bricks.Splitter
|
||||||
|
分割器控件,显示水平或垂直分割线
|
||||||
|
* [Svg](svg.md) bricks.Svg
|
||||||
|
Svg图标控件
|
||||||
|
* [StatedSvg](svg.md) bricks.StatedSvg
|
||||||
|
带状态的svg图标控件,不同状态显示不同的图标
|
||||||
|
* [MultipleStateIcon](svg.md) bricks.MultipleStateIcon
|
||||||
|
多状态图标控件
|
||||||
|
|
||||||
|
* [TabPanel](tab.md) bricks.TabPanel
|
||||||
|
页签控件
|
||||||
|
* [Tabular](tabular.md) bricks.Tabular
|
||||||
|
数据列表形式的数据维护控件,支持数据的显示,增加,修改和删除
|
||||||
|
|
||||||
|
[xls2ddl](https://git.opencomputing.cn/yumoqing/xls2ddl)工具能根据数据表结构自动生成数据Tabular控件以及相关的数据维护dspy
|
||||||
|
|
||||||
|
* [Toolbar](toolbar.md) bricks.Toolbar
|
||||||
|
工具条控件
|
||||||
|
* [Tree](tree.md) bricks.Tree
|
||||||
|
树形控件
|
||||||
|
* [VadText](vadtext.md) bricks.VadText
|
||||||
|
自动捕获语音并将捕获的语音发送给服务器
|
||||||
|
* [VideoPlayer](videoplayer.md) bricks.VideoPlayer
|
||||||
|
|
||||||
|
视频播放控件,支持浏览器支持的视频格式外,还支持m3u8流媒体和Dash流媒体,
|
||||||
|
bricks已在3parties目录中包含了所依赖的hls和dash包
|
||||||
|
|
||||||
|
* [Video](videoplayer.md) bricks.VideoPlayer
|
||||||
|
视频播放控件同VideoPlayer
|
||||||
|
* [WebSocket](websocket.md) bricks.WebSocket
|
||||||
|
|
||||||
|
支持websocket
|
||||||
|
|
||||||
|
* [WebTTS](webspeech.js.md) bricks.WebTTS
|
||||||
|
为完成控件,浏览器内置文本转语音能力
|
||||||
|
* [WebASR](webspeech.js.md) bricks.WebASR
|
||||||
|
未完成控件,浏览器内部的语音识别能力
|
||||||
|
* [Tooltip](widget.md) bricks.Tooltip
|
||||||
|
|
||||||
|
Tooltip控件,不直接创建,而是在控件中添加“tip":"提示字符串“属性为控件添加Tooltip控件
|
||||||
|
|
||||||
|
* [Text](widget.md) bricks.Text
|
||||||
|
|
||||||
|
文本控件
|
||||||
|
|
||||||
|
* [Title1](widget.md) bricks.Title1
|
||||||
|
|
||||||
|
第一号标题
|
||||||
|
|
||||||
|
* [Title2](widget.md) bricks.Title2
|
||||||
|
|
||||||
|
第二号标题
|
||||||
|
|
||||||
|
* [Title3](widget.md) bricks.Title3
|
||||||
|
|
||||||
|
第三号标题
|
||||||
|
|
||||||
|
* [Title4](widget.md) bricks.Title4
|
||||||
|
|
||||||
|
第四号标题
|
||||||
|
|
||||||
|
* [Title5](widget.md) bricks.Title5
|
||||||
|
|
||||||
|
第五号标题
|
||||||
|
|
||||||
|
* [Title6](widget.md) bricks.Title6
|
||||||
|
|
||||||
|
第六号标题
|
||||||
|
|
||||||
|
* [Wterm](wterm.md) bricks.Wterm
|
||||||
|
|
||||||
|
xterm.js在bricks中的实现
|
||||||
|
|
||||||
|
## 容器类控件
|
||||||
|
* [VScrollPanel](accordion.md) bricks.VScrollPanel
|
||||||
|
垂直滚动容器,需要设置固定的高度或占满全部父容器高度
|
||||||
|
* [HScrollPanel](accordion.md) bricks.HScrollPanel
|
||||||
|
水平滚动容器,需要设置固定的宽度或占满全部父容器宽度
|
||||||
|
* [Popup](accordion.md) bricks.Popup
|
||||||
|
弹出容器,置于当前全部控件最上面
|
||||||
|
* [PopupWindow](accordion.md) bricks.PopupWindow
|
||||||
|
弹出窗口,置于当前全部控件最上面
|
||||||
|
* [HBox](accordion.md) bricks.HBox
|
||||||
|
水平扩展容器,全部子控件水平排放
|
||||||
|
* [VBox](accordion.md) bricks.VBox
|
||||||
|
垂直扩展容器,全部子控件垂直排放
|
||||||
|
* [Filler](accordion.md) bricks.Filler
|
||||||
|
占满父容器剩余控件,如果父容器有多个Filler控件,则平均分配剩余控件,Filler容器下可添加子控件
|
||||||
|
|
||||||
|
* [DynamicColumn](dynamiccolumn.md) bricks.DynamicColumn
|
||||||
|
子控件需要设置固定宽度,动态从左到右,从上到下排列子控件
|
||||||
|
|
||||||
|
* [ResponsableBox](layout.md) bricks.ResponsableBox
|
||||||
|
自适应容器,当宽度大则水平排列子控件,而高度大时则水平排列子控件, 并能根据宽高变化自动改变。
|
||||||
|
|
||||||
|
* [Modal](modal.md) bricks.Modal
|
||||||
|
modal容器
|
||||||
108
docs/ai/wterm.md
Normal file
108
docs/ai/wterm.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# Wterm
|
||||||
|
|
||||||
|
Wterm 是一个基于 Web Terminal 的控件,用于在浏览器中嵌入一个可交互的终端界面(如 SSH、Shell 等),通过 WebSocket 与后端服务通信。该控件继承自 `bricks.JsWidget`,属于**普通控件**(非容器控件),不支持包含子控件。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要方法
|
||||||
|
|
||||||
|
| 方法名 | 参数说明 | 功能描述 |
|
||||||
|
|---------------------|---------|--------|
|
||||||
|
| `open()` | 无 | 异步初始化终端实例并建立 WebSocket 连接,加载 FitAddon 并绑定事件 |
|
||||||
|
| `destroy()` | 无 | 销毁控件时调用,清理定时任务、解绑事件、关闭 WebSocket 和终端实例 |
|
||||||
|
| `close_websocket()` | 无 | 安全关闭 WebSocket 连接,清除事件监听器 |
|
||||||
|
| `close_terminal()` | 无 | 销毁 xterm.js 终端实例 |
|
||||||
|
| `send_data(d)` | `d`: 要发送的数据字符串 | 向服务器发送输入数据(键盘输入) |
|
||||||
|
| `send_term_size()` | 无 | 向服务器发送当前终端尺寸(行、列、宽高) |
|
||||||
|
| `send_heartbeat()` | 无 | 发送心跳消息以维持连接 |
|
||||||
|
| `heartbeat()` | 无 | 心跳逻辑:若连接正常则发送心跳,并递归调度下一次心跳 |
|
||||||
|
| `term_resize()` | 无 | 响应元素大小变化事件,调整终端布局 |
|
||||||
|
| `charsize_sizing()` | 无 | 根据全局字体大小设置终端字号 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 主要事件
|
||||||
|
|
||||||
|
| 事件名 | 触发时机 | 携带数据 | 备注 |
|
||||||
|
|------------------|--------|--------|------|
|
||||||
|
| `domon` | 控件被挂载到 DOM 时触发 | 无 | 自动调用 `send_term_size()` |
|
||||||
|
| `domoff` | 控件从 DOM 卸载前触发 | 无 | 自动调用 `destroy()` 清理资源 |
|
||||||
|
| `element_resize` | 控件所在 DOM 元素尺寸改变时触发 | 无 | 绑定后自动调整终端显示 |
|
||||||
|
| `terminal-data` | (未显式派发)终端收到服务器数据时 | 解析后的消息对象 | 在 `onmessage` 中处理 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 源码例子
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "my_terminal",
|
||||||
|
"widgettype": "Wterm",
|
||||||
|
"options": {
|
||||||
|
"ws_url": "wss://example.com/api/terminal", // WebSocket 地址
|
||||||
|
"ping_timeout": 19, // 心跳间隔秒数,默认19秒
|
||||||
|
"term_options": { // 传递给 xterm.js 的配置项
|
||||||
|
"cursorBlink": true,
|
||||||
|
"theme": {
|
||||||
|
"background": "#1e1e1e",
|
||||||
|
"foreground": "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_connect",
|
||||||
|
"event": "click",
|
||||||
|
"target": "my_terminal",
|
||||||
|
"method": "open",
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "method",
|
||||||
|
"wid": "btn_disconnect",
|
||||||
|
"event": "click",
|
||||||
|
"target": "my_terminal",
|
||||||
|
"method": "close_websocket",
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script",
|
||||||
|
"wid": "my_terminal",
|
||||||
|
"event": "domon",
|
||||||
|
"target": "my_terminal",
|
||||||
|
"script": "console.log('Terminal mounted and ready.');",
|
||||||
|
"params": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "event",
|
||||||
|
"wid": "my_terminal",
|
||||||
|
"event": "domoff",
|
||||||
|
"target": "global_event_bus",
|
||||||
|
"dispatch_event": "terminal_closed",
|
||||||
|
"params": {
|
||||||
|
"terminal_id": "my_terminal"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释说明:
|
||||||
|
|
||||||
|
- `"id"`: 控件唯一标识符。
|
||||||
|
- `"widgettype": "Wterm"`: 使用已注册的 `Wterm` 控件类型。
|
||||||
|
- `"options.ws_url"`: 必须为有效的 WebSocket URL,服务端需支持文本协议通信。
|
||||||
|
- `"options.ping_timeout"`: 设置心跳频率(秒),防止连接超时断开。
|
||||||
|
- `"term_options"`: 可选地传递给 xterm.js 的渲染和行为参数。
|
||||||
|
- `binds`:
|
||||||
|
- 当按钮 `"btn_connect"` 被点击时,调用终端的 `open()` 方法启动连接。
|
||||||
|
- 当 `"btn_disconnect"` 点击时,主动关闭 WebSocket。
|
||||||
|
- 控件挂载时输出日志信息(可用于调试)。
|
||||||
|
- 控件卸载时向全局事件总线派发 `terminal_closed` 事件,通知其他模块。
|
||||||
|
|
||||||
|
> ⚠️ 注意:使用此控件前需确保页面已引入 [xterm.js](https://xtermjs.org/) 及其 FitAddon 插件,并正确配置路径。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
✅ **适用场景**:远程终端访问、Web SSH 客户端、运行日志流展示、运维操作面板等需要终端交互功能的系统。
|
||||||
137
docs/ai/xterm.md
Normal file
137
docs/ai/xterm.md
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
# Bricks控件示例
|
||||||
|
|
||||||
|
## 控件名称
|
||||||
|
**Button**
|
||||||
|
|
||||||
|
按钮控件,用于触发用户交互事件。它是一个普通控件,继承自`JsWidget`。
|
||||||
|
|
||||||
|
### 主要方法
|
||||||
|
* `setText(text: string)`: 设置按钮上显示的文本。
|
||||||
|
* `getText()`: 获取按钮当前显示的文本。
|
||||||
|
* `setEnabled(enabled: boolean)`: 启用或禁用按钮。
|
||||||
|
* `isEnabled()`: 检查按钮是否处于启用状态。
|
||||||
|
* `click()`: 模拟点击按钮,触发其绑定的事件。
|
||||||
|
|
||||||
|
### 主要事件
|
||||||
|
* `click`: 当用户点击按钮时触发。
|
||||||
|
|
||||||
|
### 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "submitBtn", // 按钮控件的唯一ID
|
||||||
|
"widgettype": "button", // 控件类型为"button"
|
||||||
|
"options": {
|
||||||
|
"text": "提交", // 初始化时按钮上显示的文本
|
||||||
|
"enabled": true, // 按钮初始为启用状态
|
||||||
|
"width": 100,
|
||||||
|
"height": 30
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "method", // 绑定一个方法调用动作
|
||||||
|
"wid": "submitBtn", // 触发事件的组件ID是此按钮自身
|
||||||
|
"event": "click", // 监听'click'事件
|
||||||
|
"target": "formPanel", // 执行目标是ID为'formPanel'的表单控件
|
||||||
|
"method": "validateAndSubmit", // 调用的方法名
|
||||||
|
"params": {} // 调用该方法时传递的参数(此处为空)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actiontype": "script", // 绑定一个脚本执行动作
|
||||||
|
"wid": "submitBtn",
|
||||||
|
"event": "click",
|
||||||
|
"script": "console.log('提交按钮被点击了'); return true;", // 执行的内联JS代码
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bricks控件示例
|
||||||
|
|
||||||
|
## 控件名称
|
||||||
|
**Container**
|
||||||
|
|
||||||
|
容器控件,用于容纳和布局其他子控件。它是一个容器控件,继承自`JsWidget`。
|
||||||
|
|
||||||
|
### 主要方法
|
||||||
|
* `addSubwidget(widgetJson: object)`: 动态向容器中添加一个新的子控件。
|
||||||
|
* `removeSubwidget(widgetId: string)`: 根据ID从容器中移除一个子控件。
|
||||||
|
* `getSubwidgets()`: 获取容器内所有子控件的列表。
|
||||||
|
* `setLayout(layoutType: string)`: 设置容器的布局方式,例如"vertical"或"horizontal"。
|
||||||
|
|
||||||
|
### 主要事件
|
||||||
|
* `onSubwidgetAdded`: 当有新的子控件被添加到容器时触发。
|
||||||
|
* `onSubwidgetRemoved`: 当有子控件从容器中被移除时触发。
|
||||||
|
|
||||||
|
### 源码例子
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "mainPanel", // 容器控件的唯一ID
|
||||||
|
"widgettype": "container", // 控件类型为"container"
|
||||||
|
"options": {
|
||||||
|
"layout": "vertical", // 布局方式为垂直排列
|
||||||
|
"width": 400,
|
||||||
|
"height": 300,
|
||||||
|
"border": "1px solid #ccc"
|
||||||
|
},
|
||||||
|
"subwidgets": [ // 包含两个子控件
|
||||||
|
{
|
||||||
|
"id": "titleLabel",
|
||||||
|
"widgettype": "label",
|
||||||
|
"options": {
|
||||||
|
"text": "用户信息",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "inputForm",
|
||||||
|
"widgettype": "container",
|
||||||
|
"options": {
|
||||||
|
"layout": "horizontal"
|
||||||
|
},
|
||||||
|
"subwidgets": [ // 子容器包含更多子控件
|
||||||
|
{
|
||||||
|
"id": "nameLabel",
|
||||||
|
"widgettype": "label",
|
||||||
|
"options": { "text": "姓名:" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "nameInput",
|
||||||
|
"widgettype": "textfield",
|
||||||
|
"options": { "placeholder": "请输入姓名" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "urlwidget", // 绑定一个远程加载动作
|
||||||
|
"wid": "nameInput",
|
||||||
|
"event": "blur", // 当输入框失去焦点时触发
|
||||||
|
"target": "validationPopup", // 将加载的控件渲染到ID为'validationPopup'的弹窗中
|
||||||
|
"mode": "replace", // 替换模式
|
||||||
|
"options": {
|
||||||
|
"url": "/api/validateName", // 远程API地址
|
||||||
|
"method": "POST", // HTTP方法
|
||||||
|
"params": { // 请求参数
|
||||||
|
"name": "$$getValue(nameInput)" // 使用datamethod获取nameInput控件的值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"actiontype": "registerfunction", // 绑定一个已注册的全局函数
|
||||||
|
"wid": "mainPanel",
|
||||||
|
"event": "onSubwidgetAdded",
|
||||||
|
"rfname": "logWidgetAddition", // 全局函数名称
|
||||||
|
"params": {
|
||||||
|
"panelId": "mainPanel" // 传递给函数的参数
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
@ -30,6 +30,50 @@ bricks采用控件这一概念来描述web GUI的显示部件,每个控件均
|
|||||||
|
|
||||||
控件的详细介绍请参看[控件说明](widgets.md)
|
控件的详细介绍请参看[控件说明](widgets.md)
|
||||||
|
|
||||||
|
### 控件扩展
|
||||||
|
如果现有的控件没法满足系统要求,bricks支持控件扩展,控件扩展需遵守:
|
||||||
|
* 控件class继承自某一个控件的class
|
||||||
|
|
||||||
|
* 按照需求实现控件逻辑
|
||||||
|
|
||||||
|
* 在需要的地方用this.dispatch触发此控件的事件
|
||||||
|
|
||||||
|
假设需要扩展一个名字叫ExtContainer的控件
|
||||||
|
```
|
||||||
|
bricks.ExtContainer = class extends bricks.VBox {
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
/* 新控件的创建代码 */
|
||||||
|
}
|
||||||
|
......
|
||||||
|
/* 对象的其他方法,在需要的时候,在某个方法中,使用this.dispatch('new_event', data)方法引发事件 */
|
||||||
|
}
|
||||||
|
bricks.register('ExtContainer', bricks.ExtContainer); /* 注册新控件 */
|
||||||
|
```
|
||||||
|
新控件的使用,example.ui
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"widgettype":"ExtContainer",
|
||||||
|
"options":{
|
||||||
|
....
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"new_event",
|
||||||
|
"actiontype":"urlwidget",
|
||||||
|
"target":"some_container",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('./some_ui.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### 事件以及事件处理
|
### 事件以及事件处理
|
||||||
每个控件都能触发所映射dom元素的事件,以及控件js类的成员函数以及祖先类的
|
每个控件都能触发所映射dom元素的事件,以及控件js类的成员函数以及祖先类的
|
||||||
成员函数中dispatch出的事件
|
成员函数中dispatch出的事件
|
||||||
|
|||||||
115
prompt.md
Normal file
115
prompt.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# 控件例子的写法
|
||||||
|
如果源码中有多个注册控件,每个控件需要按照下面的要求编写控件文档
|
||||||
|
|
||||||
|
以markdown格式编写
|
||||||
|
一级标题为控件名称
|
||||||
|
一级标题写此控件的用处,类型(普通控件或容器控件,继承自什么控件
|
||||||
|
二级标题有:
|
||||||
|
* 主要方法
|
||||||
|
* 主要事件
|
||||||
|
* 源码例子
|
||||||
|
按照bricks控件的json规范编写,并加注释
|
||||||
|
|
||||||
|
## bricks简介
|
||||||
|
**Bricks.js** 是一个基于 JavaScript 的开发的前端组件化框架,用于构建可扩展、模块化的 Web 应用程序。bricks提供开发者使用json数据开发前端界面的能力,它支持动态组件加载、事件绑定、数据实时获取、弹窗管理、国际化(i18n)、媒体流控制等功能。
|
||||||
|
|
||||||
|
bricks以控件为单位构建界面,所有控件都从一个JsWidget继承而来,bricks的控件分为普通控件和容器控件,容器控件可以有子控件,而普通控件没有子控件,在bricks的源码文件中,用”subwidgets“数组描述子控件
|
||||||
|
|
||||||
|
## bricks开发逻辑
|
||||||
|
使用json格式的原文件(以".ui“结尾)来开发前端界面,每个ui文件
|
||||||
|
|
||||||
|
### bricks源码规范
|
||||||
|
bricks使用规范化的json来描述前端界面,json数据约束如下
|
||||||
|
{
|
||||||
|
"id" # 控件id
|
||||||
|
"widgettype" # 控件类型,请看考bricks控件清单
|
||||||
|
"options" # 控件构造参数,支持控件类继承的参数
|
||||||
|
"subwidgets" # 容器类控件需要,数组形式的一到多个控件json
|
||||||
|
"binds" # 事件处理数组, 参看bind数据规范
|
||||||
|
}
|
||||||
|
|
||||||
|
当widgettype值为"urlwidget“时,options必须为
|
||||||
|
{
|
||||||
|
"url" # 从服务器中获取控件json
|
||||||
|
“params" # 参数
|
||||||
|
"method" # 缺省为“GET”
|
||||||
|
}
|
||||||
|
意思就是从服务器中用options中提供的数据从远程服务器中获取bricks控件源码,渲染到target定义的容器控件中,这种形式提供了bricks模块化编程能力,其他的widgettype值必须时bricks中注册过的控件名称,请参看bricks的控件清单
|
||||||
|
|
||||||
|
### binds数据规范
|
||||||
|
binds数组定义用户交互行为,每个绑定bind描述符包含以下结构。
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 必填 | 描述 |
|
||||||
|
|------------------|----------|------|------|
|
||||||
|
| `actiontype` | String | ✅ | 动作类型:`bricks`, `urlwidget`, `method`, `script`, `registerfunction`, `event`, `newwindow` |
|
||||||
|
| `wid` | String | ✅ | 触发事件的组件 ID |
|
||||||
|
| `event` | String | ✅ | 监听的事件名称,如 `'click'` |
|
||||||
|
| `target` | String 或 Widget | ✅ | 执行目标组件或特殊值(如 `'Popup'`) |
|
||||||
|
| `datawidget` | String | ❌ | 获取运行时数据的源组件 ID |
|
||||||
|
| `datamethod` | String | ❌ | 数据获取方法,默认 `'getValue'` |
|
||||||
|
| `dataparams` | Object | ❌ | 调用 `datamethod` 的参数 |
|
||||||
|
| `datascript` | String | ❌ | 自定义脚本获取数据 |
|
||||||
|
| `rtdata` | Object | ❌ | 静态运行时数据 |
|
||||||
|
| `conform` | Object | ❌ | 确认对话框配置,在执行前弹出确认窗口 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
各类型绑定的特定属性
|
||||||
|
|
||||||
|
#### `urlwidget` action
|
||||||
|
|
||||||
|
从远程 URL 加载组件描述并渲染。
|
||||||
|
|
||||||
|
| 属性 | 类型 | 描述 |
|
||||||
|
|--------|---------|------|
|
||||||
|
| `mode` | String | `'replace'`, `'insert'`, `'append'`,默认 `'replace'` |
|
||||||
|
| `options.method` | String | HTTP 方法,默认 `'GET'` |
|
||||||
|
| `options.params` | Object | 请求参数 |
|
||||||
|
| `options.url` | String | 远程组件 JSON 地址 |
|
||||||
|
|
||||||
|
#### `bricks` action
|
||||||
|
|
||||||
|
本地创建 Bricks 组件。
|
||||||
|
|
||||||
|
| 属性 | 类型 | 描述 |
|
||||||
|
|--------|---------|------|
|
||||||
|
| `mode` | String | 同上 |
|
||||||
|
| `options| 对象 | 符合控件源码要求的json数据,其属性widgettype的值必须时bricks已经注册的控件 |
|
||||||
|
|
||||||
|
#### `method` action
|
||||||
|
|
||||||
|
调用目标组件的方法。
|
||||||
|
|
||||||
|
| 属性 | 类型 | 描述 |
|
||||||
|
|---------|----------|------|
|
||||||
|
| `method` | String | 方法名 |
|
||||||
|
| `params` | Object | 方法参数(kwargs) |
|
||||||
|
|
||||||
|
#### `script` action
|
||||||
|
|
||||||
|
执行内联脚本。
|
||||||
|
|
||||||
|
| 属性 | 类型 | 描述 |
|
||||||
|
|---------|----------|------|
|
||||||
|
| `script` | String | 可执行 JS 代码字符串(异步函数体) |
|
||||||
|
| `params` | Object | 传入脚本的参数 |
|
||||||
|
|
||||||
|
#### `registerfunction` action
|
||||||
|
|
||||||
|
调用已注册的全局函数。
|
||||||
|
|
||||||
|
| 属性 | 类型 | 描述 |
|
||||||
|
|----------|----------|------|
|
||||||
|
| `rfname` | String | 注册函数名称 |
|
||||||
|
| `params` | Object | 函数参数 |
|
||||||
|
|
||||||
|
#### `event` action
|
||||||
|
|
||||||
|
在target控件上派发自定义事件。
|
||||||
|
|
||||||
|
| 属性 | 类型 | 描述 |
|
||||||
|
|------------------|----------|------|
|
||||||
|
| `dispatch_event` | String | 要派发的事件名 |
|
||||||
|
| `params` | Object | 携带的数据 |
|
||||||
|
|
||||||
|
---
|
||||||
Loading…
x
Reference in New Issue
Block a user