@microi.net/cli 6.2.1 → 6.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codebuddy-plugin/marketplace.json +2 -2
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.workbuddy-plugin/marketplace.json +2 -2
- package/.workbuddy-plugin/plugin.json +1 -1
- package/assets/build-meta.json +5 -5
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/mcp-server.js +147 -121
- package/scripts/microi-cli.js +62 -62
- package/scripts/microi-skills.meta.json +279 -264
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +101 -101
- package/skills/README.md +1 -1
- package/skills/app-store/SKILL.md +7 -6
- package/skills/microi-ai-application/SKILL.md +5 -5
- package/skills/microi-client-frontend/SKILL.md +21 -15
- package/skills/microi-client-frontend/references/progressive-02-8-/350/277/220/350/241/214/346/227/266/351/253/230/351/242/221/345/235/221/345/244/215/347/233/230.md +9 -1
- package/skills/microi-codex/SKILL.md +2 -0
- package/skills/microi-codex-installer/SKILL.md +6 -0
- package/skills/microi-datasource-mapping/SKILL.md +6 -0
- package/skills/microi-db-schema/SKILL.md +8 -0
- package/skills/microi-db-schema/references/form-component-options.md +7 -0
- package/skills/microi-deployment/SKILL.md +3 -3
- package/skills/microi-deployment/references/deployment-matrix.md +1 -1
- package/skills/microi-docs-coverage/references/capability-map.md +13 -13
- package/skills/microi-form-engine/SKILL.md +46 -3
- package/skills/microi-form-engine/references/business-numbering.md +70 -0
- package/skills/microi-form-engine/references/component-catalog.md +4 -0
- package/skills/microi-form-engine/references/component-config-index.md +359 -0
- package/skills/microi-form-engine/references/data-source-events.md +13 -2
- package/skills/microi-form-engine/references/form-generation-quality.md +160 -0
- package/skills/microi-form-layout/SKILL.md +1 -1
- package/skills/microi-frontend-sdk/references/progressive-01-token-/345/275/223/345/211/215/347/231/273/345/275/225/347/224/250/346/210/267/344/270/216/345/275/223/345/211/215/347/273/210/347/253/257/347/231/273/345/275/225/345/215/217/350/256/256.md +6 -0
- package/skills/microi-microservice/SKILL.md +387 -382
- package/skills/microi-microservice/references/runtime-delivery.md +15 -0
- package/skills/microi-system-delivery/SKILL.md +7 -0
- package/skills/microi-system-delivery/references/delivery-pitfalls.md +5 -0
- package/skills/microi-ui/SKILL.md +192 -192
- package/skills/microi-ui/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/234/272/346/231/257/350/223/235/345/233/276.md +183 -183
- package/skills/microi-uniapp-frontend/SKILL.md +3 -1
- package/skills/microi.v8.js +6 -4
- package/skills/module-engine/SKILL.md +13 -1
- package/skills/scripts/sync-embedded-skills.mjs +13 -0
- package/skills/ui-design/SKILL.md +227 -223
- package/skills/ui-design/assets/pattern-showcase/index.html +2 -2
- package/skills/ui-design/assets/templates/MCI-DESIGN.md +221 -206
- package/skills/ui-design/references/data-workspace-density.md +77 -0
- package/skills/ui-design/references/design-pattern-library.md +186 -184
- package/skills/ui-design/references/mci-design-contract.md +163 -163
- package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +165 -164
- package/skills/ui-design/references/progressive-03-/345/212/250/346/225/210/350/247/204/350/214/203-/344/270/260/345/257/214/344/275/206/344/270/215/345/215/241.md +237 -235
- package/skills/ui-design/references/progressive-04-/347/273/204/344/273/266/351/243/216/346/240/274/351/200/237/346/237/245.md +154 -152
- package/skills/ui-design/references/progressive-07-/351/200/237/346/237/245-/344/273/216/345/244/264/346/220/255/345/273/272/344/270/200/344/270/252/347/247/273/345/212/250/347/253/257/351/241/265/351/235/242.md +207 -207
- package/skills/uniapp-mall-assets/SKILL.md +10 -2
- package/skills/v8-crud-api/SKILL.md +2 -1
- package/skills/v8-explorer-tree/SKILL.md +22 -1
- package/skills/v8-file-upload/SKILL.md +283 -283
- package/skills/v8-file-upload/references/progressive-01-/345/205/254/346/234/211/346/241/266-vs-/347/247/201/346/234/211/346/241/266.md +7 -1
- package/skills/v8-frontend-events/SKILL.md +14 -6
- package/skills/v8-image-processing/SKILL.md +13 -2
- package/skills/v8-image-processing/references/api-reference.md +49 -3
- package/skills/v8-saas-multi-tenant/SKILL.md +6 -0
- package/skills/v8-security/SKILL.md +11 -1
- package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +6 -1
- package/skills/v8-sql-query/SKILL.md +38 -1
- package/skills/v8-sql-query/examples/business-query.js +18 -0
- package/skills/v8-table-event/SKILL.md +51 -2
- package/skills/v8-table-event/references/progressive-02-/345/211/215/347/253/257/344/272/213/344/273/266/345/220/215-v8-eventname-/345/217/257/350/203/275/347/232/204/345/200/274.md +3 -1
- package/skills/v8-utilities/references/server-api-index.md +1 -0
- package/skills/vision-engine/references/video-timeline.md +53 -0
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
> 按需读取;本文件由 SKILL.md 的原章节无损拆分。
|
|
4
4
|
|
|
5
|
-
<!-- microi-progressive:chunk id=v8-file-upload-005 sha256=
|
|
5
|
+
<!-- microi-progressive:chunk id=v8-file-upload-005 sha256=4922ff1364f2a9994d7cc47ff224e07c794e382b6f5f44b75b76ae365f7efff1 -->
|
|
6
6
|
## 公有桶 vs 私有桶
|
|
7
7
|
|
|
8
|
+
### OSS 配置不完整的诊断
|
|
9
|
+
|
|
10
|
+
- `OBJECT_STORAGE_CONFIG_INCOMPLETE` 不等于必须购买阿里云。先核对当前生效租户三参数和 SaaS `HDFS`(`Aliyun/MinIO/S3`);旧库未设置时兼容默认 Aliyun。实际使用其它提供商时,通过既有 SaaS 配置入口修正并刷新缓存,不自动切换存储或借用主租户密钥。
|
|
11
|
+
- 含按桶校验修复的 OSS `PutObject` 仅校验并初始化本次所需桶:普通 `Limit=false/null` 检查 `AliOssPublic*` 四项,`Limit=true` 检查 `AliOssPrivate*` 四项;每组为 `BucketName/Endpoint/AccessKeyId/AccessKeySecret`。只有 `Preview=true` 且有 `FileFullPathOrigin` 时额外读取私有原图;生成公有预览需两组。缺项失败关闭,错误保留 `ErrorType`、`StorageScope` 和字段名,不输出配置值。
|
|
12
|
+
- 旧后端可能把公私两套配置一并报缺。此修复不能生成有效密钥;完整微服务交付包含私有源码和公有编译产物,仍须配置相应两类存储并验证 FileServer/CDN。只完成单桶上传不等于完整发布、回滚或客户验收成功。现有 MCP 发布/上传入口可继续复用,无需改工具签名。
|
|
13
|
+
|
|
8
14
|
### 应用商城 ZIP
|
|
9
15
|
|
|
10
16
|
应用商城的 AI 应用/微服务资产禁止逐文件 Base64 持久化到数据库。源码/安装包场景可以生成 ZIP;真实在线编译目录优先使用下节的 MCP 流式发布。数据库只保存路径和校验元数据。
|
|
@@ -25,11 +25,16 @@ description: Microi 前端 V8 事件与客户端能力指南。用于编写浏
|
|
|
25
25
|
- 登录后的敏感操作使用 `V8.Identity.Verify` 完成 Passkey/严格人脸交互;前端只取得一次性 Ticket,后端接口引擎必须重算 `ActionHash` 并原子消费,不能把前端成功当作授权。
|
|
26
26
|
|
|
27
27
|
<!-- /microi-progressive:chunk -->
|
|
28
|
-
<!-- microi-progressive:chunk id=v8-frontend-events-001 sha256=
|
|
28
|
+
<!-- microi-progressive:chunk id=v8-frontend-events-001 sha256=bf7d6288bece731f78dbfa29b0e04ff56631d3693979bb91d759fe26ef92d0ec -->
|
|
29
29
|
## 字段事件(在【字段属性】中配置)
|
|
30
30
|
|
|
31
31
|
### FieldValueChange — 值变更事件(最常用)
|
|
32
32
|
|
|
33
|
+
关联回填先读 `../microi-form-engine/references/form-generation-quality.md`。`ThisValue`
|
|
34
|
+
不是固定行对象:保存格式为 Text 时可能是原始键,Department 可能是路径,多选是数组。
|
|
35
|
+
先按来源保存键解析,再逐字段回填;处理清空、改选、失败和异步代次,不从名称猜来源列。
|
|
36
|
+
只有已确认选择是行对象且保存键确为 Id 时才能读取 `V8.ThisValue.Id`,不能用于原始键或部门路径。
|
|
37
|
+
|
|
33
38
|
```javascript
|
|
34
39
|
// V8.EventName === 'FieldValueChange'
|
|
35
40
|
// V8.ThisValue — 当前字段新值
|
|
@@ -42,8 +47,11 @@ description: Microi 前端 V8 事件与客户端能力指南。用于编写浏
|
|
|
42
47
|
if (V8.LoadMode === 'Design') return;
|
|
43
48
|
|
|
44
49
|
// 选择部门 → 联动加载该部门下的人员到 联系人 控件
|
|
45
|
-
var
|
|
46
|
-
if (
|
|
50
|
+
var selection = V8.ThisValue;
|
|
51
|
+
if (Array.isArray(selection)) selection = selection.length ? selection[selection.length - 1] : '';
|
|
52
|
+
var deptId = selection && typeof selection === 'object' ? selection.Id : selection;
|
|
53
|
+
V8.FormSet('Contact', ''); // 清除原部门的联系人,不能只更换候选列表
|
|
54
|
+
if (deptId !== '' && deptId !== null && deptId !== undefined) {
|
|
47
55
|
var users = await V8.FormEngine.GetTableData('Diy_Employee', {
|
|
48
56
|
_SelectFields: ['Id', 'Name', 'Account'],
|
|
49
57
|
_Where: [['DeptId', '=', deptId]]
|
|
@@ -53,14 +61,14 @@ if (deptId) {
|
|
|
53
61
|
V8.FieldSet('Contact', 'Data', []);
|
|
54
62
|
}
|
|
55
63
|
|
|
56
|
-
//
|
|
57
|
-
|
|
64
|
+
// 对其它业务字段的回填需先取得并校验授权来源记录。
|
|
65
|
+
// 不要无条件用 V8.ThisValue.Name;Text 保存格式可能只有 Id。
|
|
58
66
|
|
|
59
67
|
// 联动显隐
|
|
60
68
|
V8.FieldSet('TaxNo', 'Visible', V8.ThisValue === '企业');
|
|
61
69
|
|
|
62
70
|
// 联动必填
|
|
63
|
-
V8.FieldSet('Reason', '
|
|
71
|
+
V8.FieldSet('Reason', 'NotEmpty', V8.ThisValue === '退款');
|
|
64
72
|
```
|
|
65
73
|
|
|
66
74
|
### FieldOnKeyup — 键盘抬起事件
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: v8-image-processing
|
|
3
|
-
description: Microi V8.Image
|
|
3
|
+
description: Microi V8.Image 服务端图像处理指南。用于图片生成、合并、水印、缩放、裁剪、格式转换、文字绘制、二维码与元数据读取,以及多页中文 PDF 的字体缓存释放、原生内存增长排查和安全 Base64/Data URI 流程。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
|
|
7
7
|
|
|
8
8
|
# Microi V8 图像处理
|
|
9
9
|
|
|
10
|
-
使用 `V8.Image`
|
|
10
|
+
使用 `V8.Image` 在服务端处理内存图片。图像操作接收对象参数并返回 `DosResult`;图片结果位于 `result.Data.FileByteBase64`。`ReleaseFontCache()` 是无参维护方法,仅返回缓存统计。
|
|
11
11
|
|
|
12
12
|
## 核心原则
|
|
13
13
|
|
|
@@ -52,6 +52,7 @@ var source = {
|
|
|
52
52
|
| 添加常规图片水印 | `V8.Image.Watermark` | `BaseImage`、`Watermark`、`Position`、`Opacity` |
|
|
53
53
|
| 生成二维码 | `V8.Image.CreateQRCode` | `Content`、`Size` |
|
|
54
54
|
| 读取宽高、格式等元数据 | `V8.Image.GetInfo` | 任一图片来源字段 |
|
|
55
|
+
| 批量文字绘制后释放字体缓存 | `V8.Image.ReleaseFontCache()` | 无参数;返回缓存字节统计,不返回图片 |
|
|
55
56
|
|
|
56
57
|
### 3. 设计合并布局
|
|
57
58
|
|
|
@@ -169,8 +170,18 @@ return result;
|
|
|
169
170
|
- 通用规则:图片文字能力必须随 `Dos.Common` 程序集嵌入许可允许再分发的中英文字体;解析顺序固定为指定/系统字体、内置字体、明确缺字错误,禁止把“请运维安装字体”作为基础文字功能的唯一方案。
|
|
170
171
|
- 自动化检查:除 Windows 单元测试外,必须在 `FONTCONFIG_FILE` 指向空字体目录的 Linux 容器中验证英文、数字、中文和不存在的 `FontFamily`,同时确认系统 `MatchCharacter` 返回空、输出存在有效文字像素且没有缺字方框。
|
|
171
172
|
|
|
173
|
+
## 多页中文绘制与字体缓存
|
|
174
|
+
|
|
175
|
+
- 先区分照片像素内存、托管堆和原生字体缓存。缩放照片不能解决字体实例累积;案例册和报表若都调用 `Create`/`Draw` 绘制中文,就共享同一字体处理路径。
|
|
176
|
+
- 使用后端 `V8.Image.ReleaseFontCache()` 在页或批次边界清理,通常放在绘制前和 `finally` 中。普通单图无需机械添加,不得逐字符调用或把它放进匿名的独立“清缓存”接口。
|
|
177
|
+
- 最小调用:`var released = V8.Image.ReleaseFontCache(); if (!released || Number(released.Code) !== 1) return released || { Code: 0, Msg: '字体缓存释放未返回结果' };`。完整绘制与失败路径示例见 [API 参考](references/api-reference.md#releasefontcache-释放字体缓存)。
|
|
178
|
+
- `BeforeBytes/AfterBytes` 是进程共享字体缓存统计;并发时缓存会重建,不能断言清零、单调下降或将差值当作 RSS 释放量。调用不强制 GC、不改限额、不清 Redis。
|
|
179
|
+
- 先确认实际 API 进程已加载包含该方法的 `Microi.V8Engine`。旧部署可明确失败,或按业务要求兼容继续并标记能力未启用;不得吞掉错误后宣称问题已修复。更新 Skills、接口代码或编译成功都不能替代程序集部署和重启。
|
|
180
|
+
|
|
172
181
|
## 验收清单
|
|
173
182
|
|
|
183
|
+
- 多页中文 PDF/图片出现 RSS 快速上升时,区分托管累计分配、托管存活堆和原生字体缓存。`V8.Image.ReleaseFontCache()` 是无参原子能力,返回 `{Code:1,Data:{BeforeBytes,AfterBytes}}`,可在每页绘制前后调用;不修改缓存限额、不强制 GC,影响进程共享字体缓存。缓存字节不是 RSS 释放量。先确认部署包含该方法,旧服务器兼容跳过必须在诊断结果中明确标记;不能仅靠文件缓存命中、重试或本地编译宣称内存问题已解决。
|
|
184
|
+
|
|
174
185
|
- 确认每个图片来源都来自受信任的内存数据,并且没有把路径或 URL 直接传给 `V8.Image`。
|
|
175
186
|
- 确认处理链中每一步都检查 `Code === 1`。
|
|
176
187
|
- 确认覆盖图层的 `ZIndex`、`X/Y` 或 `Position` 与预期一致。
|
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
15. [GetInfo 读取信息](#getinfo-读取信息)
|
|
20
20
|
16. [兼容别名](#兼容别名)
|
|
21
21
|
17. [颜色、格式与资源限制](#颜色格式与资源限制)
|
|
22
|
+
18. [ReleaseFontCache 释放字体缓存](#releasefontcache-释放字体缓存)
|
|
22
23
|
|
|
23
24
|
## 调用与返回约定
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
除无参 `ReleaseFontCache()` 外,公开方法接收一个参数对象。底层也兼容内容为 JSON 对象的字符串,但 V8 代码应优先直接传对象,并使用规范的 PascalCase 字段名。
|
|
26
27
|
|
|
27
|
-
处理成功时,除 `GetInfo` 外均返回:
|
|
28
|
+
处理成功时,除 `GetInfo` 和 `ReleaseFontCache` 外均返回:
|
|
28
29
|
|
|
29
30
|
```javascript
|
|
30
31
|
{
|
|
@@ -42,6 +43,8 @@
|
|
|
42
43
|
}
|
|
43
44
|
```
|
|
44
45
|
|
|
46
|
+
`V8.Image.ReleaseFontCache()` 返回 `{Code:1,Data:{BeforeBytes,AfterBytes}}`。这是进程共享字体缓存统计,不是 RSS 释放量;调用只释放可回收字体缓存,不修改限额或强制 GC。多页绘制可在页面前及 `finally` 中调用,正常绘制会重新建立需要的缓存;不得每个字符清理。旧服务器需升级 `Microi.V8Engine`,兼容跳过不能记录为成功。
|
|
47
|
+
|
|
45
48
|
处理失败时返回 `Code: 0`,错误说明位于 `Msg`。任何调用链都必须先判断 `Code`:
|
|
46
49
|
|
|
47
50
|
```javascript
|
|
@@ -98,7 +101,7 @@ var result = V8.Image.GetInfo({ Bytes: response.RawBytes });
|
|
|
98
101
|
|
|
99
102
|
## 公共输出参数
|
|
100
103
|
|
|
101
|
-
除 `GetInfo` 外,各方法均支持以下参数:
|
|
104
|
+
除 `GetInfo` 和无参 `ReleaseFontCache` 外,各方法均支持以下参数:
|
|
102
105
|
|
|
103
106
|
| 参数 | 默认值 | 说明 |
|
|
104
107
|
|------|--------|------|
|
|
@@ -127,9 +130,52 @@ var result = V8.Image.GetInfo({ Bytes: response.RawBytes });
|
|
|
127
130
|
| `V8.Image.Watermark(param)` | 按锚点添加图片水印 |
|
|
128
131
|
| `V8.Image.CreateQRCode(param)` | 生成二维码 |
|
|
129
132
|
| `V8.Image.GetInfo(param)` | 读取图片元数据,不重新编码 |
|
|
133
|
+
| `V8.Image.ReleaseFontCache()` | 无参;释放本进程可回收字体缓存,返回统计,不返回图片 |
|
|
130
134
|
|
|
131
135
|
`RemoveSolidBackground` 参数:内存图片来源、`Tolerance`(默认 36)、`Feather`(默认 24)、可选 `ChromaKeyColor`(如 `#00ff00`)、`EdgeConnectedOnly`(默认 false)、`SuppressGreenSpill`(默认 false)。开启边缘连通限制可保护主体内部同色区域;封闭背景孔洞可能保留,需检查输出。专门生成的纯绿幕素材可指定绿色并开启去溢绿,清除封闭绿幕孔洞及边缘混色;主体本身为绿色时不得开启。未指定抠像色时估计四角背景色。输出固定 PNG,输入上限为 20,000,000 像素,不接受任意图片 URL。
|
|
132
136
|
|
|
137
|
+
## ReleaseFontCache 释放字体缓存
|
|
138
|
+
|
|
139
|
+
签名:`V8.Image.ReleaseFontCache()`,仅后端可用,无参数。成功返回:
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
{ Code: 1, Data: { BeforeBytes: 20480, AfterBytes: 0 } }
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
以上数字仅作字段示例,不能作为预期值。失败返回 `Code:0` 和 `Msg`;方法不存在的旧程序集可能直接抛错,必须显式处理。
|
|
146
|
+
清理作用于当前进程共享的 Skia 字体缓存,不区分租户、不跨节点、不修改缓存上限或执行 GC。
|
|
147
|
+
活跃绘制仍可持有字体,并发可重新填充缓存,所以 `AfterBytes` 不保证为零,也不保证小于 `BeforeBytes`。
|
|
148
|
+
它不会清 Redis、释放照片 Base64 或保证进程 RSS 下降指定字节数。
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
// 每页或每批使用;先部署包含方法的程序集,不依赖版本号猜测运行能力。
|
|
152
|
+
function clearFonts() {
|
|
153
|
+
try {
|
|
154
|
+
var result = V8.Image.ReleaseFontCache();
|
|
155
|
+
return result || { Code: 0, Msg: '字体缓存释放未返回结果' };
|
|
156
|
+
} catch (error) {
|
|
157
|
+
return { Code: 0, Msg: '字体缓存释放不可用,请核对程序集和服务重启状态' };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
var before = clearFonts();
|
|
161
|
+
if (Number(before.Code) !== 1) return before;
|
|
162
|
+
var drawn, after;
|
|
163
|
+
try {
|
|
164
|
+
drawn = V8.Image.Create({ Width: 640, Height: 160,
|
|
165
|
+
Text: '中文报表 / Report 2026', FontSize: 32, OutputFormat: 'png' });
|
|
166
|
+
} finally {
|
|
167
|
+
after = clearFonts(); // 不覆盖原始绘图异常。
|
|
168
|
+
}
|
|
169
|
+
if (!drawn || Number(drawn.Code) !== 1) return drawn || { Code: 0, Msg: '绘制未返回结果' };
|
|
170
|
+
if (Number(after.Code) !== 1) return after;
|
|
171
|
+
return { Code: 1, Data: drawn.Data, DataAppend: { FontCache: after.Data } };
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
普通单图无需每次清理,批量中文绘制出现原生缓存增长时才使用;禁止逐字符清理。
|
|
175
|
+
如果业务必须兼容旧部署,应显式返回未启用状态,不能把成功导出等同缓存释放成功。
|
|
176
|
+
验收须通过真实 API 测试连续绘图、清理后再绘图、失败时 `finally`、旧部署及并发;
|
|
177
|
+
观察冷生成内存,不能只测命中 PDF 缓存的请求。无系统字体 Linux 须单独回归。
|
|
178
|
+
|
|
133
179
|
## Create 生成图片
|
|
134
180
|
|
|
135
181
|
### 参数
|
|
@@ -70,6 +70,12 @@ IP、端口和完整 URL 只登记入口,不提交官方 ESA 域名绑定。
|
|
|
70
70
|
`SaasPromotionSecurity.TryResolveProvisioningDomain` 必须同时兼容,单发微服务不能
|
|
71
71
|
绕过旧 API 的裸域校验。公开试用继续保持独立域名为空,不扩大匿名开通权限。
|
|
72
72
|
|
|
73
|
+
创建成功页优先将已校验、归一化的填写地址作为主入口,保留 HTTP(S)、IP、端口与
|
|
74
|
+
子路径;宿主生成的安全启动地址作为单独备用入口。未做访问探测只能说明“访问未验证”,
|
|
75
|
+
不能因状态未知就改成“待配置”或隐藏正确的填写地址。`Upgrade.Before/Target/After`
|
|
76
|
+
如 `7.6.17.0` 是数据库迁移游标,应收在升级详情中,不能标作 API/PC 产品版本。
|
|
77
|
+
API 版本仅展示可信健康结果实际回读的 `BackendVersion`,Web 版本未知时不推测。
|
|
78
|
+
|
|
73
79
|
### 推广中心与匿名空库开通
|
|
74
80
|
|
|
75
81
|
- 主租户现有 `V8.FormEngine` 允许显式指定子租户;子租户被 `V8TenantContext.EnforceOsClient`
|
|
@@ -150,9 +150,19 @@ Secret 只通过租户管理员专用端点写入租户绑定的认证密文。
|
|
|
150
150
|
- 没有字段上下文的普通上传默认保持私有安全目录;管理员可在普通 `sys_config.HdfsUploadRules` 按可信角色授予业务目录(含有界 glob)与明确公有权限。必须先拒绝实际路径中的通配符、穿越和平台保留目录,再做模式匹配;通配符不是匿名/跨租户/发布授权。微信待审图片、头像、裁剪/压缩原图等更强规则继续优先。测试同时证明公有字段/目录可用、私有请求/伪造上下文/保留目录不可绕过。
|
|
151
151
|
|
|
152
152
|
<!-- /microi-progressive:chunk -->
|
|
153
|
-
<!-- microi-progressive:chunk id=v8-security-002 sha256=
|
|
153
|
+
<!-- microi-progressive:chunk id=v8-security-002 sha256=4fbec4fff91a887a9daa2386d60375e5b411e51fd305a3d89086bc4619231144 -->
|
|
154
154
|
## 1. 防 SQL 注入
|
|
155
155
|
|
|
156
|
+
### SQL 来源与执行结构边界
|
|
157
|
+
|
|
158
|
+
业务接口引擎禁止接收前端 SQL 并执行。SQL 正文、表列、WHERE/JOIN/ORDER BY、运算符和
|
|
159
|
+
存储过程名必须来自可信服务端固定代码或白名单定义;前端仅传业务值或有限 `queryKey`。
|
|
160
|
+
禁止把 `V8.Param`、Header、URL/Form/JSON、`_RawBody` 的整段或片段经 `sql/query/rawSql/SqlWhere`
|
|
161
|
+
等别名、嵌套对象、编码解码、间接变量或跨引擎转发后执行。不能仅封禁一个参数名。
|
|
162
|
+
`.AddInParameter` 只绑定值,不能保护客户端控制的 SQL 正文;“仅 SELECT”、关键字正则、
|
|
163
|
+
只读连接或管理员登录也不能替代来源校验。受权设计期元数据与独立数据库管理 MCP 仍遵守
|
|
164
|
+
其控制面权限,不变成普通业务 SQL 代理。安全示例与负例验收见 `../v8-sql-query/SKILL.md`。
|
|
165
|
+
|
|
156
166
|
### 必须:参数化查询
|
|
157
167
|
|
|
158
168
|
```javascript
|
|
@@ -64,7 +64,7 @@ try {
|
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
<!-- /microi-progressive:chunk -->
|
|
67
|
-
<!-- microi-progressive:chunk id=v8-security-010 sha256=
|
|
67
|
+
<!-- microi-progressive:chunk id=v8-security-010 sha256=556686f6250c75b35428b7283f79769b5a450cb9f67138f6483d2ea73f235751 -->
|
|
68
68
|
## 9. Token、终端会话与租户隔离
|
|
69
69
|
|
|
70
70
|
开发 Web、H5、UniApp、小程序、App、VS Code 或 MCP 客户端时,必须同时遵守 `microi-frontend-sdk/SKILL.md` 的 Token 协议:登录传 `_ClientType`,请求头传稳定 `did`,每次响应接收新的 `authorization`,并在浏览器/应用恢复前台时检查续签。
|
|
@@ -75,6 +75,11 @@ try {
|
|
|
75
75
|
- 收到 `TokenReplaced` 时先检查同一终端是否已有新 Token,避免并发旧响应误清新登录态。
|
|
76
76
|
- 用户提示可以显示过期时长、终端类型和租户 Key,但日志、Toast、URL、截图禁止输出完整 Token。
|
|
77
77
|
|
|
78
|
+
- 平台复制的 CLI/MCP 连接必须是独立开发会话,浏览器与开发工具分别续签、撤销。CLI、VS Code、MCP 共享导入 Token 时保留已有有效签名 `Did`;不得因宿主 Header 不同反复迁移,仅缺失或 `Empty` 的历史 Did 可受控补齐。客户端解码 JWT 只用于稳定请求头,身份仍由后端验签、租户和活动缓存确定。
|
|
79
|
+
- 登录、刷新、终端清理与吊销必须在同租户、同用户轮换锁内回读最新共享会话;鉴权或终端列表读取只清洗当前投影,不得整份回写旧 Token 列表,覆盖并发签发或复活已撤销终端。
|
|
80
|
+
- 真正吊销、超出服务端续签边界、共享登录缓存丢失时,必须有效登录后重新复制并安全导入连接;禁止用 `tokenlogin`、放宽期限或重建缓存绕过。`TokenReplaced` 先检查同连接共享 Token 是否已更新,不盲目重复刷新。
|
|
81
|
+
- HTTP 200 或空身份的 `Code=1` 不是认证成功;导入/登录/续签需核验有效 Token、非空用户 `Id` 和目标租户,随后真实初始化及状态回读。本次后端兼容修复支持已发布 CLI 6.2.1,不依赖另发 Agent 产品;源码加固、平台部署和工具产品发行分别记录。
|
|
82
|
+
|
|
78
83
|
### IP 高频拦截、受信 VS Code 独立阈值与解除
|
|
79
84
|
|
|
80
85
|
- `DataAppend.SecurityBlocked=true` 是服务端已可达但当前 IP 被临时拦截,不是网络断开。前端必须展示原始 `Msg`、`Reason`、`ExpiresAtUtc`、IP 和解除建议;不能把它转换成“后端 API 服务暂时不可用”。直接返回该结果的安全中间件必须在 CORS 之后。
|
|
@@ -9,6 +9,29 @@ description: Microi V8 安全 SQL 查询指南。用于选择 V8.FormEngine _Whe
|
|
|
9
9
|
|
|
10
10
|
你正在开发 Microi 吾码平台的 V8 引擎代码。数据库查询有两种方式:`V8.FormEngine`(推荐)和 `V8.Db`(原始 SQL)。必须遵守安全规范。
|
|
11
11
|
|
|
12
|
+
## 业务接口禁止接收客户端 SQL(强制)
|
|
13
|
+
|
|
14
|
+
接口引擎的 SQL 正文与执行结构只能来自可信、受版本管理的服务端代码或服务端白名单查询定义。
|
|
15
|
+
前端只传业务值,或有限的 `queryKey` / 排序键,由服务端映射为固定查询;值使用 `_Where` 或
|
|
16
|
+
`.AddInParameter()` 绑定。参数化只能保护值,不能让不可信 SQL 正文本身变安全。
|
|
17
|
+
|
|
18
|
+
- 禁止将 `V8.Param`、Header、URL、Form、JSON、`_RawBody` 中的完整 SQL 或片段传给
|
|
19
|
+
`FromSql/Execute*`。`sql/query/rawSql/SqlWhere/SqlJoin/orderBy` 只是例子;改名、嵌套、
|
|
20
|
+
Base64/加密、间接变量或转发另一个引擎,都不能改变来源不可信的事实。
|
|
21
|
+
- 禁止透传客户端表名、列名、运算符、WHERE/JOIN/ORDER BY 或存储过程名。需要动态排序时,
|
|
22
|
+
只允许有限业务键映射为服务端固定列与方向;未知键拒绝。FormEngine 受权字段筛选协议仍可用,
|
|
23
|
+
自建业务接口须限定字段/操作符并追加不可被客户端覆盖的用户、租户和业务范围。
|
|
24
|
+
- “仅 SELECT”、禁分号/关键字正则、只读连接、已登录/管理员、转义或参数绑定都不能代替上述来源边界。
|
|
25
|
+
不为普通业务新建通用 SQL 执行代理或匿名 SQL 接口。
|
|
26
|
+
- 发布前检查从请求源到 SQL 执行点的数据流,包括别名和嵌套调用;用未知业务参数、伪造查询键、
|
|
27
|
+
SQL 片段与越权用户负例验证拒绝,正常参数验证固定 SQL 与绑定值分离。
|
|
28
|
+
|
|
29
|
+
[可执行安全示例](examples/business-query.js) 展示 `Input` 白名单、固定查询键/排序映射与本人范围。
|
|
30
|
+
示例不是通用授权器,正式业务仍应校验所需角色、动作、数据范围和数据库方言。
|
|
31
|
+
管理员设计期保存的字段 SQL、模块 `SqlWhere/SqlJoin` 与独立受控的数据库管理 MCP 工具属于控制面;
|
|
32
|
+
这些能力仍保留原权限与审计,不能据此生成前端可传 SQL 的业务接口。服务端合法参数化
|
|
33
|
+
`V8.Db.FromSql` 能力不变。
|
|
34
|
+
|
|
12
35
|
## 性能门禁(必须执行)
|
|
13
36
|
|
|
14
37
|
写接口引擎前必须先做数据访问计划,避免“循环套循环查数据库”:
|
|
@@ -85,7 +108,7 @@ V8.FormEngine.GetTableData('Table', { _Where: objectWhere });
|
|
|
85
108
|
|
|
86
109
|
## 次选:V8.Db.FromSql(仅 SQL 字符串 + AddInParameter)
|
|
87
110
|
|
|
88
|
-
> **⚠️ FormEngine 优先原则:** 增删改操作(INSERT / UPDATE / DELETE)必须**优先**使用 `V8.FormEngine.AddFormData` / `UptFormData` / `UptFormDataByWhere` / `DelFormData`
|
|
111
|
+
> **⚠️ FormEngine 优先原则:** 增删改操作(INSERT / UPDATE / DELETE)必须**优先**使用 `V8.FormEngine.AddFormData` / `UptFormData` / `UptFormDataByWhere` / `DelFormData` 等方法。只有多表 JOIN、复杂子查询、GROUP BY 聚合等 FormEngine 无法表达的场景,或下文明确要求保留业务修改时间的原子计数,才使用参数化 SQL。
|
|
89
112
|
|
|
90
113
|
> **⚠️ FromSql 调用规则:** `V8.Db.FromSql` 在 V8 中只传 SQL 字符串,不要把动态值作为第二个或后续参数传给 `FromSql`。动态值必须用链式 `.AddInParameter('@p0', value)` 绑定;否则会生成平台不支持的调用签名。
|
|
91
114
|
|
|
@@ -224,6 +247,20 @@ try {
|
|
|
224
247
|
}
|
|
225
248
|
```
|
|
226
249
|
|
|
250
|
+
## 仅更新计数而保留业务修改时间
|
|
251
|
+
|
|
252
|
+
普通 `FormEngine.UptFormData` 会自动推进系统 `UpdateTime`,不能靠 `_NotSaveField` 抑制。
|
|
253
|
+
浏览量、收藏量等不代表内容修改的计数,如果业务明确要求保持修改时间与版本,允许使用
|
|
254
|
+
当前事务中的固定列、参数化原子 SQL;权限校验、目标定位和公开范围仍沿用原流程。
|
|
255
|
+
计数增量使用 `Count = COALESCE(Count,0) + 1`,不能先读后写丢失并发增量。
|
|
256
|
+
收藏等同时写状态与总数的场景须在同一事务锁定固定业务行,更新状态、聚合总数并回读;
|
|
257
|
+
重复请求保持幂等,禁止手动提交接口引擎事务。SQL 不得顺带修改 `UpdateTime` 或内容版本。
|
|
258
|
+
|
|
259
|
+
列表使用修改时间排序时,要明确权威时间、空值与非法日期的回退、稳定唯一键平局规则,
|
|
260
|
+
有时区ISO值与无时区审计值混用时,先查明该业务的权威时区并归一到同一时间轴,不能按浏览器或执行进程的本地TZ解析。
|
|
261
|
+
并在服务端全局排序后分页,不能只排序已加载的首屏。验收同时回读计数、原始时间、版本,
|
|
262
|
+
覆盖重复请求、超过一页、非空旧业务日期加较新系统修改日期;不要通过改历史日期或单条特殊置顶掩盖问题。
|
|
263
|
+
|
|
227
264
|
## 绝对禁止
|
|
228
265
|
|
|
229
266
|
```javascript
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// 本示例只接受 Input 内业务参数;真实入口还须校验本业务的当前用户、角色与动作权限。
|
|
2
|
+
// 查询正文、表列和排序结构全部来自服务端常量,前端只选择有限 queryKey / sort 键。
|
|
3
|
+
var input = JSON.parse(JSON.stringify(V8.Param.Input || {}));
|
|
4
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) return { Code: 0, Msg: 'Input 必须为对象' };
|
|
5
|
+
var allowed = ['queryKey', 'status', 'sort'];
|
|
6
|
+
if (Object.keys(input).some(function (key) { return allowed.indexOf(key) < 0; })) return { Code: 0, Msg: '包含不支持的业务参数' };
|
|
7
|
+
if (!V8.CurrentUser || !V8.CurrentUser.Id) return { Code: 1001, Msg: '请先登录' };
|
|
8
|
+
if (input.queryKey !== 'my-orders') return { Code: 0, Msg: '查询类型无效' };
|
|
9
|
+
if (['Pending', 'Completed'].indexOf(input.status) < 0) return { Code: 0, Msg: '状态无效' };
|
|
10
|
+
var sorts = { 'created-desc': ' ORDER BY CreateTime DESC, Id DESC', 'amount-desc': ' ORDER BY Amount DESC, Id DESC' };
|
|
11
|
+
var sort = input.sort === undefined ? 'created-desc' : input.sort;
|
|
12
|
+
if (typeof sort !== 'string' || !Object.prototype.hasOwnProperty.call(sorts, sort)) return { Code: 0, Msg: '排序无效' };
|
|
13
|
+
// 当前用户归属条件不可由前端 userId / 租户 / SQL 片段覆盖。分页为此有界查询的固定上限。
|
|
14
|
+
var rows = V8.Db.FromSql('SELECT Id, Code, Amount, Status FROM Biz_Order WHERE IsDeleted = 0 AND UserId = @userId AND Status = @status' + sorts[sort] + ' LIMIT 20')
|
|
15
|
+
.AddInParameter('@userId', V8.CurrentUser.Id)
|
|
16
|
+
.AddInParameter('@status', input.status)
|
|
17
|
+
.ToArray();
|
|
18
|
+
return { Code: 1, Data: rows };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: v8-table-event
|
|
3
|
-
description: Microi V8
|
|
3
|
+
description: Microi V8 表单事件开发。用于表单进入/提交/数据处理,以及日志、评论、数据版本各四阶段写入事件的源码发现、事务、幂等回执和验收。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
|
|
@@ -51,7 +51,7 @@ AI 本地开发表单 V8 事件时,优先修改 `microi-v8-engine/<租户>/<
|
|
|
51
51
|
| `DataFilterV8.js` | **后端** | `DataFilter` | 获取列表/表单数据后 | 每行数据加工、脱敏、补充字段 |
|
|
52
52
|
|
|
53
53
|
<!-- /microi-progressive:chunk -->
|
|
54
|
-
<!-- microi-progressive:chunk id=v8-table-event-002 sha256=
|
|
54
|
+
<!-- microi-progressive:chunk id=v8-table-event-002 sha256=470d1827cce01a45e424639cc7273c7b838c8e158f125bff524466393c1e4b41 -->
|
|
55
55
|
## 事件触发规则
|
|
56
56
|
|
|
57
57
|
- 后端 V8 事件 / 接口引擎中调用 `V8.FormEngine` 增删改 → **不触发**表单 V8 事件
|
|
@@ -60,6 +60,55 @@ AI 本地开发表单 V8 事件时,优先修改 `microi-v8-engine/<租户>/<
|
|
|
60
60
|
- 服务器端提交前/后 V8 事件在**同一事务**中执行
|
|
61
61
|
- `diy_table.V8Limit` 是表后端提交前、提交后和数据处理 V8 的正向开关:缺失、`null`、`0/false` 均不设置 Jint 单次超时、语句、函数递归和累计分配预算,只有 `1/true` 才启用这些限制。旧 `V8Unlimited` 仅在新字段不存在时反向推断,新的 MCP、Manifest 和应用资源只写 `V8Limit`。进程常驻内存、取消、并发、接口嵌套深度、权限和数据库保护始终生效。
|
|
62
62
|
|
|
63
|
+
### 日志、评论、数据版本的 12 个写入事件
|
|
64
|
+
|
|
65
|
+
事件仍是顶层 `diy_table` 属性,不属于 `sys_menu`、字段 Config 或临时接口。
|
|
66
|
+
`microi_list_events/get_event_code/save_event_code` 与 Manifest `events[]` 使用相同名称。
|
|
67
|
+
`V8.EventName` 等于属性名去掉末尾 `V8`。
|
|
68
|
+
|
|
69
|
+
| 属性/EventType | 中文名称 |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `DataLogBeforeClientV8` | 前端数据日志写入前V8事件 |
|
|
72
|
+
| `DataLogBeforeServerV8` | 后端数据日志写入前V8事件 |
|
|
73
|
+
| `DataLogAfterServerV8` | 后端数据日志写入后V8事件 |
|
|
74
|
+
| `DataLogAfterClientV8` | 前端数据日志写入后V8事件 |
|
|
75
|
+
| `DataCommentBeforeClientV8` | 前端数据评论写入前V8事件 |
|
|
76
|
+
| `DataCommentBeforeServerV8` | 后端数据评论写入前V8事件 |
|
|
77
|
+
| `DataCommentAfterServerV8` | 后端数据评论写入后V8事件 |
|
|
78
|
+
| `DataCommentAfterClientV8` | 前端数据评论写入后V8事件 |
|
|
79
|
+
| `DataVersionBeforeClientV8` | 前端数据版本写入前V8事件 |
|
|
80
|
+
| `DataVersionBeforeServerV8` | 后端数据版本写入前V8事件 |
|
|
81
|
+
| `DataVersionAfterServerV8` | 后端数据版本写入后V8事件 |
|
|
82
|
+
| `DataVersionAfterClientV8` | 前端数据版本写入后V8事件 |
|
|
83
|
+
|
|
84
|
+
顺序为前端 BeforeClient → 后端 BeforeServer → 写活动 → 后端 AfterServer → 提交 → 前端 AfterClient。
|
|
85
|
+
仅该类功能启用、且该类四事件至少一项非空时启用新原子管线;全空保持存量日志/版本流程,
|
|
86
|
+
不得据此声称旧异步流程也具有新事务保证。无浏览器调用只执行两个后端阶段,读取、计数、
|
|
87
|
+
预览不触发。后端任一失败或异常向外传播并回滚父事务;跨不同 writer/辅助库无法共享事务时
|
|
88
|
+
必须拒绝并回滚,不能静默拆成两个事务。AfterServer 仍在提交前。
|
|
89
|
+
|
|
90
|
+
- `V8.Form` 是活动行的白名单增量,不是父业务整行;`V8.OldForm` 为适用的旧活动或空。
|
|
91
|
+
`V8.Activity={Kind,Action,ParentTableId,ParentTableName,ParentRecordId,RequestId}`;
|
|
92
|
+
`V8.Param` 只含 Activity 与 Form 的副本。
|
|
93
|
+
- 后端 `TableModel` 是权威父表,`CurrentUser` 来自真实会话,`DbTrans` 共享父事务。
|
|
94
|
+
不信任前端传来的表模型、后端脚本、用户或绕过标志,不向普通客户端返回六个 Server 事件源码。
|
|
95
|
+
- 客户端 `_ActivityData` 只允许 `DataLog.Title`、`DataVersion.Remark`。评论的 Content /
|
|
96
|
+
ParentCommentId 与日志 `_DataLog` 继续按既有入口传递。Version.Data 必须由服务器实际行重建,
|
|
97
|
+
客户端提交前只能预览和校验,不能替换审计快照。
|
|
98
|
+
- `DataAppend.RecordActivities` 仅包含实际新写活动的类型、动作、Id 等元数据,不含内容或代码;
|
|
99
|
+
无差异、无操作、幂等重放不触发 AfterClient。客户端提交后拿到的是本地合法草稿、回执元数据
|
|
100
|
+
和正常 Result,不是数据库最终权威快照;前端失败不能撤销已提交记录,也不能诱导自动重放。
|
|
101
|
+
- 通过标准保存工具维护版本头、回读代码并确认 `mic_data_version`;父行/菜单/活动权限、
|
|
102
|
+
幂等、事件防递归与租户隔离仍需同时满足。
|
|
103
|
+
- 清空事件必须真正保存空字符串,不补一段只有版本头的空脚本,否则仍会被视为已配置事件。
|
|
104
|
+
清空动作仍由原代码版本链记录;本地空代码不生成事件文件。
|
|
105
|
+
- 新评论管线在事件加工前,由服务器对规范化原始 Content + ParentCommentId 计算
|
|
106
|
+
`diy_comment.RequestHash`(varchar(64)、可空、隐藏只读),与 RequestId 一起核验重试;
|
|
107
|
+
BeforeServer 修改 Content 不改变原请求摘要。客户端和事件不能提交或覆盖该摘要。
|
|
108
|
+
老记录摘要为空时沿用原内容/父评论匹配;新评论事件启用而缺少物理摘要列时必须明确提示升级,
|
|
109
|
+
不得静默退化或使用临时修复接口。
|
|
110
|
+
|
|
111
|
+
|
|
63
112
|
<!-- /microi-progressive:chunk -->
|
|
64
113
|
<!-- microi-progressive:chunk id=v8-table-event-003 sha256=271cf2359a152663040ed31ecc2289836df4d32d0fc9c47735dffbf9b59b9837 -->
|
|
65
114
|
## ⚠️ 关键陷阱(必读)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 按需读取;本文件由 SKILL.md 的原章节无损拆分。
|
|
4
4
|
|
|
5
|
-
<!-- microi-progressive:chunk id=v8-table-event-011 sha256=
|
|
5
|
+
<!-- microi-progressive:chunk id=v8-table-event-011 sha256=e2ae9d89779e1f31eef74faa34a9e5a35ac1ba2b9f86cd5c112875eeae5a42e0 -->
|
|
6
6
|
## 前端事件名(V8.EventName 可能的值)
|
|
7
7
|
|
|
8
8
|
| 值 | 说明 |
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
| `FormIn` | 进入表单事件 |
|
|
11
11
|
| `FormSubmitBefore` | 提交前事件 |
|
|
12
12
|
| `FormOut` | 离开表单事件 |
|
|
13
|
+
| `Data{Log|Comment|Version}BeforeClient` / `AfterClient` | 相应活动写入前/后前端事件,属性名带 V8,EventName 不带 |
|
|
14
|
+
| `Data{Log|Comment|Version}BeforeServer` / `AfterServer` | 相应活动写入前/后后端事件;AfterServer 仍在提交事务前 |
|
|
13
15
|
| `FieldValueChange` | 字段值变更事件 |
|
|
14
16
|
| `FieldOnKeyup` | 文本框键盘事件 |
|
|
15
17
|
| `TableFieldOnKeyup` | 表格行内文本框键盘事件 |
|
|
@@ -166,6 +166,7 @@ outbox 编排放在接口引擎。密钥从当前租户 `V8.SysConfig.ServerPriv
|
|
|
166
166
|
| TCP | `V8.Tcp.Send/SendAsync/SendAndReceive/SendAndReceiveAsync`;原始字节与出站安全见 `v8-tcp-integration` |
|
|
167
167
|
| IoT 设备原连接下行 | `V8.IoT.Send({DeviceId,CommandId,FrameHex,ExpireSeconds})`;可信接口 Key、协议配置、Redis 路由及执行回执边界见 `v8-tcp-integration`,不包含厂家业务操作 |
|
|
168
168
|
| 图片 | `V8.Image.Create/Merge/Overlay/Watermark/Resize/Crop/Rotate/Flip/Draw/Convert/GetInfo/CreateQRCode` |
|
|
169
|
+
| 字体缓存维护 | `V8.Image.ReleaseFontCache()`,后端无参;批量中文绘制的页边界使用,返回缓存统计而非图片或 RSS;用法及部署检查见 `v8-image-processing` |
|
|
169
170
|
| Office | `V8.Office.ExportExcel/ExcelToList/ExportWord/ExportPowerPoint/SendEmail` |
|
|
170
171
|
| OCR | `await V8.OCR.Recognize({...})`;服务端租户配置与调用参数隔离,详见 `ocr-engine` |
|
|
171
172
|
| 文件 | `V8.HDFS`、`V8.Method.Upload/GetPrivateFileUrl` |
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
- 默认单帧窗口、一个在途请求,按0/1/2秒固定媒体游标连续分析,不按播放时钟跳点;协议最多8帧不是弱CPU应请求8帧。Grant约110秒、作业120秒,超时不延旧框;已Accept的帧仍通过ReadWindow权威回读。
|
|
18
18
|
- 准确率优先模式默认等待已接受、显示窗口已回读的连续区段;可显式切换流畅预览,未知不计入有效统计。无效但已分析的帧可观看,不变成有效观测;最后不足一秒按实际覆盖报告。手动暂停撤销播放意图,等待门不得用晚回执重开。seek仅切显示与ReadWindow,不重置分析游标;单在途回读只保留最新定位意图,最多3次退避,空回执不是成功。
|
|
19
19
|
- TimelineFrame包含实际PTS、requestedTime、frameId、imageSha256和完整来源绑定。平台逐序号CAS保存OriginalFrame/Result/State,不把前瞻统计写到当前session.ResultJson。浏览器只在原PTS到达时显示相应统计;实际解码帧回调建立纹理锚点,遮挡/断流/过期清除,不能把旧框硬贴当前画面。
|
|
20
|
+
- 准确优先暂停等待时也要投影已回读窗口:若视频仍停在同一已解码原时刻,采集该帧的灰度纹理后再恢复播放,不能只依赖播放中的帧回调。原时刻短窗口可直接绘制可信框;短窗口之外必须通过当前纹理跟随,不扩大旧框容差或修改考勤。
|
|
20
21
|
- 手机只用一个视频解码器、小灰度纹理缓冲与有界轮询,不下载神经网络。脸框独立验证;可跟踪同帧真实人体来辅助脸位移,但不能补造未检测到的脸、身体或身份。
|
|
21
22
|
- 切服务前固定原作业连接快照,取消不能请求新节点。倒退清未来行为候选;历史通过ReadSummary只读查看,不猜分析代次或继续旧考勤。恢复识别关闭本人的旧Active会话并新建,导出按权威历史摘要标明分析范围与覆盖率;ThroughTime以前最近已接受帧的累计摘要不等于完整事件清单,行为只含该最新帧复核。
|
|
22
23
|
|
|
@@ -26,6 +27,50 @@
|
|
|
26
27
|
|
|
27
28
|
前端最多单在途、最高2Hz,隐藏/暂停/换源取消,原图灰度纹理有界跟随。快脸叠层不得修改人数、无人、身份、行为或考勤;未检出脸不是无人。单模型70ms不能当作鉴权网络和RF并发后的端到端时延,需另测P95与物理手机温控。
|
|
28
29
|
|
|
30
|
+
## 当前画面人体定位与服务器跟踪
|
|
31
|
+
|
|
32
|
+
录像默认连续播放时,历史分析从零逐秒推进不能承担当前画面的唯一定位来源。播放、相机与监控均应自动开启独立当前帧通道;它不能按播放时钟跳过历史考勤,也不能把位置框转成员工身份。
|
|
33
|
+
|
|
34
|
+
当前行为候选应使用节点缓存的原帧引用(用户/租户/会话/序号/时刻/图片摘要绑定),不能接受浏览器自报框。结果保留原采样时刻与 Candidate/Unvalidated,不提交正式考勤或行为数量。小目标 DetailInsufficient 与模型 ReviewTimedOut 必须显式保留;模型已配置不等于完成复核或准确率达标。Linux MPEG-TS 回归必须在实际交付镜像执行,不能以 Windows 同用例通过替代。
|
|
35
|
+
|
|
36
|
+
节点源码候选 1.9.9 的 `/person-locations` 使用 `VisionPersonLocations/1` 独立签名域,绑定当前登录用户、租户、会话、原采样序号/时刻/图像摘要和模型摘要。只有目标 capabilities 实际声明并且普通帐号真实推理通过,才能称已接通;发布页面不等于部署节点。未验收基线、未知区域、局部人体、模型置信度和训练集命中都不能证明 90%。
|
|
37
|
+
|
|
38
|
+
慢检测需要跟踪时,应评测真实当前像素的服务器跟踪,分别限制原帧缓存、原生线程、重放年龄、目标数和 CPU。KCF/CSRT 的 `update=true` 本身不是当前人仍存在的证据:必须测试遮挡、换景、纹理相似物和人员消失,验证当前外观并清除失效框。手机继续禁止连续神经网络推理;服务器跟踪的效果、丢框率、NAS P95 和物理温控需独立验收。
|
|
39
|
+
|
|
40
|
+
### 当前帧候选协议与跟随验收
|
|
41
|
+
|
|
42
|
+
应用 1.9.16 / 节点 1.9.9 的当前帧通路仍是候选。节点须实际声明 `serverTrackingReady`、协议、传输方式和已登记算法,前端在建会话时快照固定算法;不能由响应自行切换或接受未知算法。此通路与连续历史统计、身份、图库和行为证据分离。
|
|
43
|
+
|
|
44
|
+
- `/tracking-frames` 返回独立签名 `VisionTrackingFrame/1`,绑定 tenant/owner/session/source/generation/sequence/time、JPEG/原像素摘要、模型和检测锚点。浏览器不能自报框。当前默认采集长边最多640、总像素最多230400,200–500ms反馈节拍;1280/921600只保留协议兼容。5Hz是采样上限,不是吞吐承诺。
|
|
45
|
+
- `/tracking-batches` 使用 `VisionTrackingBatch/1`,一次鉴权的协议上限是5张/5MiB;当前客户端冷启动1张,按预算最多升至3张,只有一个HTTP在途。采集、待发、在途和待显示合计最多10槽;满时丢新图,缺口绑定随后首张实际入队图,不提前破坏仍连续的旧队列。
|
|
46
|
+
- 每帧只显示同一JPEG解码的bitmap与坐标,按原PTS延迟播放;新模式关闭手机NCC灰度搜索/重放。源PTS间隔>.6秒、序号缺口、换源和变代必须重锚,不能伪造每秒帧号。画面寿命从采集起最多6秒,空采样/停用清屏;局部过期只释放自身,有效在途批次不因另一帧过期而撤销。HTTP超时/取消须等原请求和native工作排空后才准入下一项。
|
|
47
|
+
- 当前算法为 `OpenCV-KCF-face384-relative-rest640+initial-appearance+fresh-anchor/5`。大脸锚点按相对面积≥`65536/(1280*720)`、ROI短边/画面短边≥`96/720`选384/82944工作图,其余人体/小脸为640/230400;只是计算档位,摘要、外观和归一化输出仍基于原图。不能把工作图变小理解成模型精度自然不变。
|
|
48
|
+
- 普通 `TrackingLost` 与人脸核心超预算可在同原图真实复检一次;人体 `TrackingDeadlineExceeded` 则保持Unknown、下一帧复锚,不在同帧追加慢人员推理。复检仍失败则未知。旧检测锚墙钟过期后,只有本帧已有新检测、源锚年龄和最近有效像素年龄均≤2.5秒,才可经当前KCF、初始整体/分块外观及IoU一对一关联续接匿名ID;最终框/摘要来自新检测。KCF-only旧锚过期、3秒闲置、250ms核心预算、.55/.20外观阈值、遮挡/交叉拒绝和租户/用户隔离继续有效。不能强留旧ID或旧框凑连续时长。
|
|
49
|
+
- 候选身份池只复用固定可信API的HTTP连接;每个请求继续核验本次DiyToken/租户,复制白名单认证头,拒收/发送Cookie、环境代理与重定向,不缓存用户或权限,不把续签Token写默认头。401/403与平台503分开,续签只属于本次响应。池由同事件循环lifespan持有,节点工作排空后关闭,启动失败也关闭;不能以连接复用省略授权校验。
|
|
50
|
+
- 实际显示验收读取canvas绘制成功后写入的高精度 `presentedPts/presentedSequence/presentedFramehash`,清屏/绘制失败必须与像素同时撤销。不能把整秒HUD、待发队列时间、服务端已回包时间或未成功绘制的元数据当已呈现;最终候选源码、真实显示与Linux/目标设备回执分别绑定。
|
|
51
|
+
|
|
52
|
+
CPU候选镜像必须在Python数值库导入前固定标准 `OPENBLAS_NUM_THREADS/OMP_NUM_THREADS/MKL_NUM_THREADS=1`;它们是第三方节点线程参数,不得加入Microi API业务环境变量。`cv2.setNumThreads(1)`不会限制其它BLAS池。生产依赖的真实读回曾显示NumPy与OpenCV各16线程,2CPU三帧对照仅限池后移动KCF为48ms,默认284ms;原生框/NCC/门限相同。该方向回执不代替Linux全闭包、真实端到端、NAS或物理手机温控,纯灰度失跟反例必须保留,不降低原阈值。CUDA构建须由调用方显式传已验固定CPU摘要,不能沿用旧1.9.8默认或宣称GPU已验收。
|
|
53
|
+
|
|
54
|
+
输入分辨率诊断必须把原始帧与产品640/230400/JPEG.78采样后的帧分组并冻结字节摘要;把640再放大1280不能恢复细节。固定四train图、10已标人员的同权重完整80类诊断,原图1280为TP8/FP0/FN2/U0,产品640JPEG再送1280为TP4/FP3/FN6/U1;80%/40%召回不是独立专家盲验,更不是90%结论。不得据此登记模型或调整原标签/阈值;仍需原帧采集设计、训练/诊断隔离、未知分母和新人工真值。
|
|
55
|
+
|
|
56
|
+
手机/粗指针设备设置最小采样间隔500ms,桌面保持原200–500ms反馈;batch恢复/失败/probe和legacy single路径均不能越过手机下限。该调整不改变.6秒源缺口、6秒画面寿命、10槽或2秒连续验收,不把降低JPEG工作量写成真机不发热保证。
|
|
57
|
+
|
|
58
|
+
这仍是HTTP采样后的同步画面,完整手机WebRTC上传和同步视频/坐标回传尚未实现。不能据它宣称百路摄像头容量、原视频全帧轨迹或物理手机不发热。部署仍复用原 `vision/behavior/media`,不因新增跟踪协议增加常驻容器;CPU通道与固定版本/摘要、Watchtower白名单须分别回读,自动更新器启动不等于新候选已经部署。
|
|
59
|
+
|
|
60
|
+
跟随验收分别记录真实Detection/Tracking、同ID原PTS连续时长、实际DOM框连续时长、丢框/换ID、当前帧摘要、未知覆盖与P95。重复同图、模拟clock、指定ROI、单帧出框和协议200都不能当独立泛化准确率;缩采样纹理漂移须保留失败,不改阈值或把清框回归描述成连续通过。安全帽、手机使用、可见拍摄和身份仍需各自独立真值,实验模型未合格保留候选或未知。源码、Linux、目标NAS、真实手机温控和各项90%门禁逐层报告,不以某层通过替代其它层。
|
|
61
|
+
|
|
62
|
+
## 登记录像原生帧显示通道
|
|
63
|
+
|
|
64
|
+
`VisionFileDisplayFrame/1` 是与旧Timeline/Tracking域隔离的源码候选。`GrantDisplayFrame`只核当前用户、本人Active File会话、封存对象和固定pipeline,不写Revision、TimelineStateJson、统计、身份或图库。POST只返作业元数据,即使Completed幂等重放也不带图片;GET逐次重新鉴权及重查媒体授权后才返图,不能凭旧grant继续返回撤权图片。平台连接池拒Cookie,不缓存权限;单worker、取消后原生排空、最多8记录/1完成JPEG和TTL均有界。
|
|
65
|
+
|
|
66
|
+
先支持可信登记H264播放件的原生BGR24解码,不在检测前scale/JPEG;旋转/SAR/编码或PTS语义不支持时明确拒绝。YOLOX-S1280派生完整80类模型固定SHA `b043286f955262e16f5a7dbf09f35511bf0cecc9591285ee71cfa1d71a956110`,原640模型协议不变。YuNet同帧定位仅产生脸框和faceKnown,不提模板或猜身份。三摘要分别表示文件、原像素、实际展示JPEG字节,不互换。
|
|
67
|
+
|
|
68
|
+
前端File仅按绘制成功actualPTS推进,最多一作业/一bitmap;seek、暂停、换源、隐藏和错误撤销旧代,晚回包不能复活。原正式时间轴继续按既有规则分析,显示只按实际已呈现时刻回读sealed投影;显示通道不扩大有效覆盖或自动授权采集。摄像头/直播维持v5,完整WebRTC与物理温控另验。能力必须实际ready才启用;已发布RC2不含此后续源码通道,不能给旧启动器添加未知配置项。
|
|
69
|
+
|
|
70
|
+
四train原图1280召回80%、缩图再放大40%、固定分块未改善,均不是独立90%验证。原生取帧、连接、模型文件回读和单帧出框不能替代人员/脸/安全帽/手机/拍摄各自的独立验收。
|
|
71
|
+
|
|
72
|
+
含人员模型的节点候选使用独立Docker模型层,固定 `/opt/microi-vision/models` 两个公开权重及其大小/SHA/来源/完整许可通知;不进Git、NuGet或浏览器包,不在运行中下载或扫描任意目录,不写NAS只读模型挂载。显式配置优先,缺省auto,`bundled_models=disabled`关闭回退,JSON null不是可靠关闭语义。实际普通UID必须可遍历目录并读取只读文件;构建前后来源、/app运行闭包、/opt模型白名单、标签/摘要、NAS及回滚分别验收。不能把独立模型层理解成客户模型质量或CPU通道已更新。
|
|
73
|
+
|
|
29
74
|
## 身份、图库与候选
|
|
30
75
|
|
|
31
76
|
- Grant由会话明确 `enableIdentity && identityConsent` 决定identityPolicy;capturePolicy同时要求runtime.CanCaptureFaces和会话captureFaces未关闭。变更开关新建会话,不能沿用旧授权。
|
|
@@ -39,3 +84,11 @@
|
|
|
39
84
|
固定旧权重来源是 onnx-community/rfdetr_large-ONNX@4988fbacee4aa815e43c2e0666377ab26bddf1e8(560输入)。`tile-small-v2`指小目标补充分块算法,不证明权重为Small。模型卡及当时官方COCO权重声明Apache-2.0;HF导出缺原始PT摘要与完整导出脚本,不能声称已证明每个张量溯源,也不能把其它代次规格自动归同一许可。逐模型保留来源/SHA/第三方通知。
|
|
40
85
|
|
|
41
86
|
协议/单测通过不等于目标NAS吞吐、手机温控、海康兼容或90%准确率通过。实际推理时延、解码Range预算、播放覆盖率、边框精度、行为分项正反样本、身份误接受/误拒绝分别验收。没有独立真值则保留未验收,不能用模型置信度或人工诊断少量图替代。
|
|
87
|
+
|
|
88
|
+
## 专用CPU安全帽候选与慢任务隔离
|
|
89
|
+
|
|
90
|
+
v1.9.18开发候选使用同视觉容器中的受控DAMO ONNX,独立`VisionHelmetCandidates/1`及`damoyolo-safetyhelmet-person-head-roi-v1`;model SHA固定ff2a83c668d520ca0fbd4d7cb420cfdfaf42f8fc8e6e4a33efd0146754f5d4f6。人员上部/可信脸附近取原生ROI,不resize,最多6个、单ROI262144/总524288 padded像素。>.6只是候选门,不能绕正式行为门或作为90%依据;手机/拍摄分项不得由安全帽就绪推导为正常。
|
|
91
|
+
|
|
92
|
+
File结果绑定同原生像素/PTS与父签名;Camera/Live仅已登记HTTPS直连支持的新端点复用原跟踪JPEG及签名。当前/待播同帧才画候选,迟到仅显示原时刻历史卡,不套当前图。一个候选lease仍计入原10槽,6秒寿命不延长,不新增JPEG采集/编码/浏览器模型。源签名2秒龄期由同节点判,提交使用收到跟踪回执后的本地performance期限,不能假设手机和NAS墙钟一致。旧节点/平台中继不支持该端点时不发送无效任务;手机/粗指针关闭旧本地纹理扫描回退,PC兼容另验。
|
|
93
|
+
|
|
94
|
+
PPE单槽无队列。超时先Unknown并将槽交内部drain持有,底层真实结束前仍Busy;不能同步等待慢PPE而卡住已完成的body/face,也不能提前释放槽并启动第二路native。迟到结果不补写旧签名帧,主动取消/关闭仍真实排空。关联冲突、无头、超预算、触边或故障为Unknown,未关联头部只显示候选线索,不制造员工违规、人数、考勤、身份或图库记录。验证含旧超时行为确实失败、新行为及时返回且槽未提前释放、真实模型分层耗时及普通用户HTTP;未取得NAS/真机/独立精度回执前保持开发候选。
|