@microi.net/cli 4.9.5 → 4.9.7
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/README.md +7 -12
- package/assets/build-meta.json +6 -5
- package/package.json +1 -1
- package/scripts/mcp-server.js +83 -83
- package/scripts/microi-cli.js +80 -92
- package/scripts/microi-codex-broker.js +418 -0
- package/scripts/microi-codex-router.js +159 -65
- package/scripts/microi-skills.meta.json +349 -190
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +3566 -0
- package/skills/ai-engine/SKILL.md +1 -1
- package/skills/ai-platform-governance/SKILL.md +22 -167
- package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -0
- package/skills/app-store/SKILL.md +1 -1
- package/skills/business-blueprint/SKILL.md +1 -1
- package/skills/datasource-engine/SKILL.md +1 -1
- package/skills/dos-orm/SKILL.md +1 -1
- package/skills/job-engine/SKILL.md +1 -1
- package/skills/message-notification/SKILL.md +1 -1
- package/skills/microi-ai-application/SKILL.md +1 -1
- package/skills/microi-client-frontend/SKILL.md +18 -435
- package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +144 -0
- 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 +178 -0
- package/skills/microi-client-frontend/references/progressive-03-vue3-/345/211/215/347/253/257/345/276/256/346/234/215/345/212/241/345/256/277/344/270/273/350/247/204/345/210/231.md +144 -0
- package/skills/microi-codex/SKILL.md +4 -4
- package/skills/microi-codex-installer/SKILL.md +25 -36
- package/skills/microi-datasource-mapping/SKILL.md +1 -1
- package/skills/microi-db-schema/SKILL.md +4 -4
- package/skills/microi-db-schema/references/schema-overview.md +1 -1
- package/skills/microi-db-schema/references/schema.md +1 -1
- package/skills/microi-db-schema/references/table-catalog.md +1 -1
- package/skills/microi-deployment/SKILL.md +1 -1
- package/skills/microi-docs-coverage/SKILL.md +1 -1
- package/skills/microi-form-engine/SKILL.md +2 -2
- package/skills/microi-form-layout/SKILL.md +20 -226
- package/skills/microi-form-layout/references/progressive-01-3-/344/270/211/347/247/215/345/210/206/347/273/204/347/232/204/345/255/230/345/202/250/344/270/216/351/205/215/347/275/256.md +235 -0
- package/skills/microi-frontend-sdk/SKILL.md +18 -152
- 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 +171 -0
- package/skills/microi-left-right-layout/SKILL.md +1 -1
- package/skills/microi-microservice/SKILL.md +8 -1
- package/skills/microi-microservice/references/runtime-delivery.md +4 -0
- package/skills/microi-mobile-app-quality/SKILL.md +23 -289
- package/skills/microi-mobile-app-quality/references/progressive-01-4-/351/207/215/350/246/201/346/214/211/351/222/256/345/277/205/351/241/273/345/270/246/345/233/276/346/240/207.md +209 -0
- package/skills/microi-mobile-app-quality/references/progressive-02-9-/344/270/273/351/242/230/345/210/207/346/215/242/345/277/205/351/241/273/347/234/237/345/256/236/344/270/224/345/205/250/345/261/200/347/224/237/346/225/210.md +117 -0
- package/skills/microi-solution-quotation/SKILL.md +1 -1
- package/skills/microi-system-delivery/SKILL.md +17 -381
- package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +186 -0
- package/skills/microi-system-delivery/references/progressive-02-/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/345/277/205/351/241/273/350/246/206/347/233/226/347/232/204/345/235/221.md +210 -0
- package/skills/microi-ui/SKILL.md +20 -170
- 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 -0
- package/skills/microi-uniapp-frontend/SKILL.md +27 -336
- package/skills/microi-uniapp-frontend/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/210/206/347/261/273-/345/217/214/346/240/217/345/210/227/350/241/250/347/213/254/347/253/213/346/273/232/345/212/250.md +225 -0
- package/skills/microi-uniapp-frontend/references/progressive-02-/345/205/263/351/224/256/344/270/232/345/212/241/350/265/204/344/272/247/344/270/215/345/276/227/351/273/230/350/256/244/351/200/211/344/270/255.md +154 -0
- package/skills/module-engine/SKILL.md +1 -1
- package/skills/ocr-engine/SKILL.md +1 -1
- package/skills/page-engine/SKILL.md +24 -272
- package/skills/page-engine/references/progressive-01-/346/211/200/346/234/211/347/273/204/344/273/266/347/261/273/345/236/213.md +234 -0
- package/skills/page-engine/references/progressive-02-/347/211/210/346/234/254/345/216/206/345/217/262-/345/271/266/345/217/221/344/277/235/345/255/230/344/270/216/345/233/236/346/273/232.md +60 -0
- package/skills/performance-testing/SKILL.md +1 -1
- package/skills/playwright-e2e/SKILL.md +25 -591
- package/skills/playwright-e2e/references/progressive-01-/345/205/250/350/207/252/345/212/250/347/231/273/345/275/225-/345/205/215/351/252/214/350/257/201/347/240/201-/344/275/206/344/270/215/345/205/215/345/257/206/347/240/201-/345/277/205/350/257/273.md +173 -0
- package/skills/playwright-e2e/references/progressive-02-/346/226/207/345/255/227/345/257/271/346/257/224/345/272/246/344/270/216/345/217/257/350/257/273/346/200/247/350/207/252/345/212/250/345/214/226/346/243/200/346/237/245-/345/277/205/345/201/232.md +183 -0
- package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +221 -0
- package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +69 -0
- package/skills/print-engine/SKILL.md +1 -1
- package/skills/production-readonly-audit/SKILL.md +1 -1
- package/skills/report-engine/SKILL.md +1 -1
- package/skills/scripts/optimize-progressive-disclosure.mjs +204 -0
- package/skills/scripts/refresh-progressive-disclosure.mjs +64 -0
- package/skills/scripts/validate-progressive-disclosure.mjs +52 -0
- package/skills/search-engine/SKILL.md +1 -1
- package/skills/spider-engine/SKILL.md +1 -1
- package/skills/translate-engine/SKILL.md +1 -1
- package/skills/ui-design/SKILL.md +27 -1462
- package/skills/ui-design/references/progressive-01-/351/242/234/350/211/262/344/275/223/347/263/273-css-variables-/346/224/257/346/214/201/344/270/273/351/242/230/345/210/207/346/215/242.md +218 -0
- package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +155 -0
- 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 +235 -0
- 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 +152 -0
- package/skills/ui-design/references/progressive-05-/347/247/273/345/212/250/347/253/257/344/270/223/347/224/250/350/247/204/350/214/203.md +238 -0
- package/skills/ui-design/references/progressive-06-/344/270/273/351/242/230/345/210/207/346/215/242/345/256/236/347/216/260.md +194 -0
- 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 -0
- package/skills/ui-design/references/progressive-08-/350/241/250/345/215/225/345/210/206/347/273/204/350/247/204/350/214/203-tabs-vs-collapsegroup-/345/274/272/345/210/266.md +142 -0
- package/skills/uniapp-mall-assets/SKILL.md +1 -1
- package/skills/unity-integration/SKILL.md +1 -1
- package/skills/v8-api-config/SKILL.md +1 -1
- package/skills/v8-cache-pattern/SKILL.md +1 -1
- package/skills/v8-crud-api/SKILL.md +21 -246
- package/skills/v8-crud-api/references/progressive-01-/346/237/245/350/257/242/345/210/227/350/241/250-/345/210/206/351/241/265.md +226 -0
- package/skills/v8-crud-api/references/progressive-02-where-/346/235/241/344/273/266/350/257/255/346/263/225/351/200/237/346/237/245.md +49 -0
- package/skills/v8-debugging/SKILL.md +1 -1
- package/skills/v8-explorer-tree/SKILL.md +1 -1
- package/skills/v8-export-import/SKILL.md +16 -426
- package/skills/v8-export-import/references/progressive-01-excellayout-/351/253/230/347/272/247/350/207/252/347/224/261/345/270/203/345/261/200.md +211 -0
- package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +202 -0
- package/skills/v8-export-import/references/progressive-03-/345/256/211/345/205/250-/346/200/247/350/203/275/346/263/250/346/204/217.md +42 -0
- package/skills/v8-file-upload/SKILL.md +17 -355
- 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 +227 -0
- package/skills/v8-file-upload/references/progressive-02-office-/346/226/207/344/273/266/345/234/250/347/272/277/347/274/226/350/276/221/347/211/210/346/234/254/345/217/267/350/247/204/345/210/231.md +149 -0
- package/skills/v8-formengine-http/SKILL.md +1 -1
- package/skills/v8-frontend-events/SKILL.md +20 -206
- package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +219 -0
- package/skills/v8-http-integration/SKILL.md +15 -237
- package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +220 -0
- package/skills/v8-http-integration/references/progressive-02-/351/224/231/350/257/257/345/244/204/347/220/206/346/250/241/345/274/217.md +44 -0
- package/skills/v8-image-processing/SKILL.md +1 -1
- package/skills/v8-menu-buttons/SKILL.md +16 -512
- package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +221 -0
- package/skills/v8-menu-buttons/references/progressive-02-8-/346/250/241/345/274/217-f-/345/220/216/345/217/260/344/273/273/345/212/241/346/214/211/351/222/256-/351/225/277/344/273/273/345/212/241.md +224 -0
- package/skills/v8-menu-buttons/references/progressive-03-10-/345/217/215/346/250/241/345/274/217-/351/201/277/345/205/215.md +104 -0
- package/skills/v8-mongodb/SKILL.md +1 -1
- package/skills/v8-mq-mqtt/SKILL.md +12 -176
- package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +181 -0
- package/skills/v8-saas-multi-tenant/SKILL.md +1 -1
- package/skills/v8-security/SKILL.md +17 -330
- package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +199 -0
- package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +158 -0
- package/skills/v8-sql-query/SKILL.md +1 -1
- package/skills/v8-table-event/SKILL.md +17 -237
- package/skills/v8-table-event/references/progressive-01-informv8-js-/350/241/250/345/215/225/346/211/223/345/274/200/344/272/213/344/273/266.md +216 -0
- 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 +46 -0
- package/skills/v8-template-engine/SKILL.md +1 -1
- package/skills/v8-utilities/SKILL.md +1 -1
- package/skills/v8-workflow/SKILL.md +20 -161
- package/skills/v8-workflow/references/progressive-01-/350/212/202/347/202/271/345/274/200/345/247/213-v8-/344/272/213/344/273/266.md +180 -0
- package/skills/workspace-conventions/SKILL.md +36 -369
- package/skills/workspace-conventions/references/progressive-01-/347/211/210/346/234/254/346/233/264/346/226/260/346/227/245/345/277/227/344/277/235/346/212/244/350/247/204/345/210/231-/345/274/272/345/210/266.md +208 -0
- package/skills/workspace-conventions/references/progressive-02-microi-net-api-/346/234/254/345/234/260/345/220/257/345/212/250/347/272/246/345/256/232.md +196 -0
- package/skills/workspace-conventions/references/progressive-03-cli-/344/270/216-ide-/346/217/222/344/273/266/351/224/231/347/211/210/345/205/261/345/255/230/347/272/246/345/256/232.md +27 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# v8-export-import 详细参考 1
|
|
2
|
+
|
|
3
|
+
> 按需读取;本文件由 SKILL.md 的原章节无损拆分。
|
|
4
|
+
|
|
5
|
+
<!-- microi-progressive:chunk id=v8-export-import-004 sha256=828669707ddc19320767ac4b787383136ec820deb6ad1dc861b42b5d39097677 -->
|
|
6
|
+
## `ExcelLayout` 高级自由布局
|
|
7
|
+
|
|
8
|
+
审批单、套打表、主子表、多级表头和复杂合并单元格不要硬塞入 `ExcelData + ExcelHeader`。改用 `ExcelLayout`:
|
|
9
|
+
|
|
10
|
+
```javascript
|
|
11
|
+
var excelResult = V8.Office.ExportExcel({
|
|
12
|
+
OsClient: V8.OsClient,
|
|
13
|
+
ExcelSheets: [{
|
|
14
|
+
SheetName: '审批单',
|
|
15
|
+
ExcelLayout: {
|
|
16
|
+
Cells: [
|
|
17
|
+
// 先给整块区域统一画细网格
|
|
18
|
+
{ Range: 'A1:H10', Style: {
|
|
19
|
+
FontName: 'Microsoft YaHei', BorderStyle: 'Thin', BorderColor: '7F8C9A',
|
|
20
|
+
VerticalAlignment: 'Center', WrapText: true
|
|
21
|
+
}},
|
|
22
|
+
// 后写入的非空样式属性叠加/覆盖,可以再加标题和外框
|
|
23
|
+
{ Range: 'A1:H1', Value: '盘盈亏及报废申请表', Merge: true, Style: {
|
|
24
|
+
Bold: true, FontSize: 18, HorizontalAlignment: 'Center',
|
|
25
|
+
BorderTopStyle: 'Medium', BorderTopColor: '34495E'
|
|
26
|
+
}},
|
|
27
|
+
{ Range: 'A2', Value: '序号', Style: { Bold: true }},
|
|
28
|
+
{ Range: 'G2', Value: '数量', Style: { Bold: true }},
|
|
29
|
+
{ Range: 'H2', Value: '金额', Style: { Bold: true }},
|
|
30
|
+
{ Range: 'A3', Value: 1 },
|
|
31
|
+
{ Range: 'G3', Value: 2, DataType: 'Number' },
|
|
32
|
+
{ Range: 'H3', Formula: 'G3*1200', Style: { NumberFormat: '#,##0.00' }},
|
|
33
|
+
{ Range: 'A8:G8', Value: '合计', Merge: true, Style: { Bold: true, HorizontalAlignment: 'Right' }},
|
|
34
|
+
{ Range: 'H8', Formula: 'SUM(H3:H7)', Style: { Bold: true, NumberFormat: '#,##0.00' }},
|
|
35
|
+
{ Range: 'A9:D9', Value: '(1) 申请人:张三(已电子签)', Merge: true },
|
|
36
|
+
{ Range: 'E9:H9', Value: '(2) 主管意见:同意(已电子签)', Merge: true }
|
|
37
|
+
],
|
|
38
|
+
MergedRanges: [],
|
|
39
|
+
Columns: [{ Column: 'A', Width: 9 }, { Column: 'H', Width: 16 }],
|
|
40
|
+
Rows: [{ Row: 1, Height: 42 }, { Row: 2, Height: 32 }],
|
|
41
|
+
RowGroups: [{ StartRow: 3, EndRow: 7, Collapsed: false }]
|
|
42
|
+
},
|
|
43
|
+
ExcelOptions: {
|
|
44
|
+
ShowGridLines: false,
|
|
45
|
+
FreezeRows: 2,
|
|
46
|
+
FreezeColumns: 1,
|
|
47
|
+
AutoFilterRange: 'A2:H8',
|
|
48
|
+
PrintOrientation: 'Landscape',
|
|
49
|
+
PaperSize: 'A4',
|
|
50
|
+
FitToWidth: 1,
|
|
51
|
+
PrintArea: 'A1:H10',
|
|
52
|
+
ShowPageNumber: true
|
|
53
|
+
}
|
|
54
|
+
}]
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
规则:
|
|
59
|
+
|
|
60
|
+
- `Range` 使用 `A1` / `A1:K15`,不允许跨 Sheet 的 `Sheet1!A1`;`Value/Formula` 写入左上角,样式作用于全部单元格。
|
|
61
|
+
- `Merge:true` 合并当前 `Range`;也可集中传 `MergedRanges`。不完全相同的合并区域不得重叠。
|
|
62
|
+
- `DataType` 可传 `String/Number/Boolean/DateTime/Blank`,不传时按值推断;公式可带或不带 `=`。
|
|
63
|
+
- `Columns` 用列字母或从 1 开始的 `Index`,支持 `Width/Hidden/AutoSize/MinWidth/MaxWidth`;`Rows.Row`、`RowGroups.StartRow/EndRow` 均从 1 开始。
|
|
64
|
+
- 主表/子表使用 `RowGroups` 生成 Excel 原生展开/折叠行,不要只靠缩进文本模拟层级。
|
|
65
|
+
- 先给实际数据块统一网格样式,再用小范围样式叠加标题、表头、合计和外框,可以显著减少 V8 代码重复。
|
|
66
|
+
- 官方完整接口引擎 `export-excel-advanced-demo` 一次导出 5 Sheet,覆盖截图同款申请单、主子表、复杂合并表头、标准表格和边框样式库。
|
|
67
|
+
- 高级布局会为覆盖区域创建真实单元格。不要对整列或百万行套样式;只配置实际使用区域,避免不必要的内存和 CPU。
|
|
68
|
+
|
|
69
|
+
### 匿名下载与 OnlyOffice 在线预览配套模式
|
|
70
|
+
|
|
71
|
+
响应文件接口本身可以同时作为浏览器下载地址和 OnlyOffice 文件源:
|
|
72
|
+
|
|
73
|
+
- `export-excel-advanced-demo` 开启【响应文件】,返回 `FileName/ContentType/FileByteBase64`,可配置 `AllowAnonymous=1` 供客户直接下载。
|
|
74
|
+
- `export-excel-advanced-demo-preview` 也开启【响应文件】和【允许匿名】,直接响应同一 `.xlsx`;它的完整 HTTP 地址可以传给 `/online-office?fileUrl=...`。V8 接口不需要先上传 HDFS,也不返回 `FileUrl/OnlineOfficePath` JSON;在线页面会调用后端安全中转,透明缓存到当前租户公有 HDFS 后再交给 OnlyOffice。
|
|
75
|
+
- `fileUrl` 必须整体 URL 编码,同时传 `fileName`(或 `fileType`)让 OnlyOffice 确定类型。
|
|
76
|
+
- 匿名 `fileUrl` 只能是当前平台正式 `ApiBase`,或同端口本地后端可读取的 loopback `/apiengine/...`;路径或 query 必须显式携带当前 `OsClient`,禁止接受任意外部 URL,避免 SSRF。
|
|
77
|
+
- 开发环境传入 `localhost/127.0.0.1` 时,只允许当前同端口后端读取源接口。后端按 URL 与文件名的 SHA-256 使用确定性 `/{OsClient}/office-preview/...` 路径写入公有对象存储,Redis 共享缓存 10 分钟;OnlyOffice 使用公网 `FileServer` 地址。中转限制 50MB、不跟随重定向并校验 Office/PDF 文件头,禁止实现成任意 URL 代理。
|
|
78
|
+
- 匿名链接只能用于可公开数据。敏感数据必须关闭匿名调用、上传私有桶,并要求登录后由 `/api/HDFS/OpenPrivateFile` 审计代理提供临时地址。
|
|
79
|
+
|
|
80
|
+
配套预览接口核心写法:
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
var exportResult = V8.ApiEngine.Run('export-excel-advanced-demo', {});
|
|
84
|
+
if (!exportResult || exportResult.Code != 1 || !exportResult.Data || !exportResult.Data.FileByteBase64) {
|
|
85
|
+
V8.Result = exportResult && exportResult.Code != 1
|
|
86
|
+
? exportResult
|
|
87
|
+
: { Code: 0, Msg: 'Excel 生成失败' };
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// 当前接口配置:AllowAnonymous=1、ResponseFile=1、StopHttp=0。
|
|
91
|
+
V8.Result = exportResult;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
预览 URL 形式:`/?OsClient=tenant_demo#/online-office?fileUrl=<URL编码后的接口地址>&fileName=示例.xlsx&fileType=xlsx&canEdit=0`。`canEdit` 只是编辑申请,不是授权依据;未登录时即使传 `canEdit=1` 也必须强制只读,并隐藏左侧菜单、顶部导航和页签。公网匿名文件接口应配置频率限制或让导出逻辑足够轻量,不能依赖进程内变量控制并发。
|
|
95
|
+
|
|
96
|
+
<!-- /microi-progressive:chunk -->
|
|
97
|
+
<!-- microi-progressive:chunk id=v8-export-import-005 sha256=401c2cd0a4b9ea45b1709d14277cf71d74ab29dcda72d404f452a0e67b56eddc -->
|
|
98
|
+
## 多 Sheet Excel 导出
|
|
99
|
+
|
|
100
|
+
`ExcelSheets` 中每项是一张独立工作表,可以使用 `ExcelLayout` 高级布局,也可以传 `ExcelData + ExcelHeader` 标准表格;标准表格还可传 `FormEngineKey`、查询条件等让后端自行查询。两种模式可以在同一工作簿混用。`Sheets` 是兼容别名;新代码统一使用 `ExcelSheets`。
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
var excelResult = V8.Office.ExportExcel({
|
|
104
|
+
OsClient: V8.OsClient,
|
|
105
|
+
ExcelOptions: {
|
|
106
|
+
DefaultColumnWidth: 14,
|
|
107
|
+
HeaderRowHeight: 28,
|
|
108
|
+
HeaderStyle: { Bold: true, BackgroundColor: 'D9EAF7' }
|
|
109
|
+
},
|
|
110
|
+
ExcelSheets: [
|
|
111
|
+
{
|
|
112
|
+
SheetName: '订单',
|
|
113
|
+
ExcelData: orderList,
|
|
114
|
+
ExcelHeader: [
|
|
115
|
+
{ Name: 'OrderNo', Label: '订单号', Component: 'Text', Width: 22 },
|
|
116
|
+
{ Name: 'Amount', Label: '金额', Component: 'NumberText', Type: 'decimal', Width: 16, NumberFormat: '#,##0.00' }
|
|
117
|
+
],
|
|
118
|
+
ExcelOptions: { FreezeHeader: true, AutoFilter: true }
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
SheetName: '客户',
|
|
122
|
+
ExcelData: customerList,
|
|
123
|
+
ExcelHeader: [
|
|
124
|
+
{ Name: 'Name', Label: '客户名称', Component: 'Text', Width: 24 },
|
|
125
|
+
{ Name: 'Phone', Label: '联系电话', Component: 'Text', Width: 18 }
|
|
126
|
+
],
|
|
127
|
+
ExcelOptions: { DataRowHeight: 22 }
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
});
|
|
131
|
+
if (excelResult.Code !== 1) return excelResult;
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
Code: 1,
|
|
135
|
+
Data: {
|
|
136
|
+
FileName: '业务数据.xlsx',
|
|
137
|
+
ContentType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
138
|
+
FileByteBase64: System.Convert.ToBase64String(excelResult.Data)
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`SheetName` 会自动处理 Excel 非法字符、31 字符上限和重名。未传 `ExcelHeader` 时,可以在每个 Sheet 中传 `TableId`、`FormEngineKey`、`_Where`、`_OrderBy`、`_PageSize` 等查询参数,并继承外层的 `OsClient`、`TableId`、`_SysMenuId` 等默认值。外层 `ExcelOptions` 也是所有 Sheet 的默认值;Sheet 内的 `ExcelOptions` 只覆盖已传属性。
|
|
144
|
+
|
|
145
|
+
图片列:`ImgUpload.Multiple=1` 会按最大图片数展开为多列并合并表头;列上的 `Width` 会应用到每个展开列,`DataRowHeight/RowHeight` 控制图片行高。自动列宽会遍历单元格,大批量导出不要对所有列盲目开启。
|
|
146
|
+
|
|
147
|
+
<!-- /microi-progressive:chunk -->
|
|
148
|
+
<!-- microi-progressive:chunk id=v8-export-import-006 sha256=1a74f8359e67ca4b270de414000f8416a7564c1595189c091281d0fea6dd4a45 -->
|
|
149
|
+
## Word 导出
|
|
150
|
+
|
|
151
|
+
新代码使用对象参数的 `ExportWord`;`ExportWordText` 继续保留,只用于兼容旧版纯文本场景。Word 的页面边距、图片宽高单位为厘米,字体大小单位为磅。
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
var wordResult = V8.Office.ExportWord({
|
|
155
|
+
Title: '月度经营报告',
|
|
156
|
+
Subtitle: DateNow('yyyy年MM月'),
|
|
157
|
+
Author: V8.CurrentUser.Name,
|
|
158
|
+
Subject: '经营分析',
|
|
159
|
+
Keywords: '经营,月报',
|
|
160
|
+
PageSize: 'A4', // A4 | Letter
|
|
161
|
+
Orientation: 'Portrait', // Portrait | Landscape
|
|
162
|
+
MarginTop: 2.2,
|
|
163
|
+
MarginRight: 2.0,
|
|
164
|
+
MarginBottom: 2.2,
|
|
165
|
+
MarginLeft: 2.0,
|
|
166
|
+
FontFamily: 'Microsoft YaHei',
|
|
167
|
+
FontSize: 10.5,
|
|
168
|
+
TitleFontSize: 20,
|
|
169
|
+
HeaderText: '吾码经营中心',
|
|
170
|
+
FooterText: '内部资料',
|
|
171
|
+
ShowPageNumber: true,
|
|
172
|
+
Paragraphs: [
|
|
173
|
+
{ Text: '本月经营情况总体稳定。', FirstLineIndent: 0.74 },
|
|
174
|
+
{ Text: '以下数据未经授权不得外传。', Bold: true, FontColor: 'C00000' }
|
|
175
|
+
],
|
|
176
|
+
Sections: [{
|
|
177
|
+
Heading: '一、核心指标',
|
|
178
|
+
HeadingLevel: 1,
|
|
179
|
+
Content: '本节展示主要经营指标。',
|
|
180
|
+
Tables: [{
|
|
181
|
+
Title: '指标明细',
|
|
182
|
+
Headers: ['指标', '本月', '同比'],
|
|
183
|
+
Rows: [['销售额', 1280000, '12.5%'], ['订单数', 860, '8.1%']],
|
|
184
|
+
ColumnWidths: [4, 4, 4],
|
|
185
|
+
HeaderBackgroundColor: 'D9EAF7'
|
|
186
|
+
}]
|
|
187
|
+
}],
|
|
188
|
+
Images: [{
|
|
189
|
+
FileByteBase64: chartBase64, // 支持纯 Base64 或 data URI
|
|
190
|
+
FileName: 'chart.png',
|
|
191
|
+
ContentType: 'image/png',
|
|
192
|
+
Width: 15,
|
|
193
|
+
Height: 8,
|
|
194
|
+
Alignment: 'Center',
|
|
195
|
+
Caption: '图 1:趋势分析'
|
|
196
|
+
}]
|
|
197
|
+
});
|
|
198
|
+
if (wordResult.Code !== 1) return wordResult;
|
|
199
|
+
return {
|
|
200
|
+
Code: 1,
|
|
201
|
+
Data: {
|
|
202
|
+
FileName: '月度经营报告.docx',
|
|
203
|
+
ContentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
204
|
+
FileByteBase64: System.Convert.ToBase64String(wordResult.Data)
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
段落支持 `Text/Alignment/Bold/Italic/Underline/FontFamily/FontSize/FontColor/SpacingBefore/SpacingAfter/LineSpacing/FirstLineIndent/PageBreakBefore`。章节支持 `Heading/HeadingLevel/Content/Paragraphs/Tables/Images/PageBreakBefore`;表格支持 `Headers/Rows/ColumnWidths/Alignment/HeaderBold/HeaderBackgroundColor/HeaderFontColor/BorderColor/FontSize`。
|
|
210
|
+
|
|
211
|
+
<!-- /microi-progressive:chunk -->
|
package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# v8-export-import 详细参考 2
|
|
2
|
+
|
|
3
|
+
> 按需读取;本文件由 SKILL.md 的原章节无损拆分。
|
|
4
|
+
|
|
5
|
+
<!-- microi-progressive:chunk id=v8-export-import-007 sha256=d2958751b32d5143693cbdb6fb72aeca97f450c80c360aa7d826d4f6595c0ab1 -->
|
|
6
|
+
## PowerPoint 导出
|
|
7
|
+
|
|
8
|
+
PowerPoint 的幻灯片尺寸、图片/表格位置与宽高单位均为英寸,默认画布为 16:9(13.333 × 7.5)。
|
|
9
|
+
|
|
10
|
+
```javascript
|
|
11
|
+
var pptResult = V8.Office.ExportPowerPoint({
|
|
12
|
+
Title: '季度经营汇报',
|
|
13
|
+
Author: V8.CurrentUser.Name,
|
|
14
|
+
Subject: '季度复盘',
|
|
15
|
+
Company: '吾码',
|
|
16
|
+
SlideWidth: 13.333,
|
|
17
|
+
SlideHeight: 7.5,
|
|
18
|
+
FontFamily: 'Microsoft YaHei',
|
|
19
|
+
BackgroundColor: 'FFFFFF',
|
|
20
|
+
TitleColor: '17365D',
|
|
21
|
+
TextColor: '222222',
|
|
22
|
+
TitleFontSize: 28,
|
|
23
|
+
BodyFontSize: 18,
|
|
24
|
+
ShowSlideNumber: true,
|
|
25
|
+
Slides: [
|
|
26
|
+
{
|
|
27
|
+
Layout: 'TitleSlide',
|
|
28
|
+
Title: '季度经营汇报',
|
|
29
|
+
Subtitle: DateNow('yyyy-MM-dd')
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
Layout: 'TitleAndContent',
|
|
33
|
+
Title: '核心结论',
|
|
34
|
+
Bullets: ['收入保持增长', '重点客户续约稳定'],
|
|
35
|
+
TextItems: [
|
|
36
|
+
{ Text: '风险:回款周期延长', Bullet: true, Level: 0, Bold: true, FontColor: 'C00000' }
|
|
37
|
+
],
|
|
38
|
+
Tables: [{
|
|
39
|
+
Headers: ['指标', '本期', '目标'],
|
|
40
|
+
Rows: [['销售额', '128万', '120万']],
|
|
41
|
+
X: 0.7, Y: 4.0, Width: 11.9, Height: 2.2,
|
|
42
|
+
HeaderBackgroundColor: '17365D'
|
|
43
|
+
}]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
Title: '趋势图',
|
|
47
|
+
Images: [{
|
|
48
|
+
FileByteBase64: chartBase64,
|
|
49
|
+
FileName: 'trend.png',
|
|
50
|
+
ContentType: 'image/png',
|
|
51
|
+
X: 1.2, Y: 1.5, Width: 10.9, Height: 5.2
|
|
52
|
+
}]
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
if (pptResult.Code !== 1) return pptResult;
|
|
57
|
+
return {
|
|
58
|
+
Code: 1,
|
|
59
|
+
Data: {
|
|
60
|
+
FileName: '季度经营汇报.pptx',
|
|
61
|
+
ContentType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
62
|
+
FileByteBase64: System.Convert.ToBase64String(pptResult.Data)
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`Layout` 支持 `TitleSlide`、`TitleAndContent`。单页支持独立覆盖 `BackgroundColor/TitleColor/TextColor/TitleFontSize/BodyFontSize`。`TextItems` 支持 `Text/Level/Bullet/Bold/Italic/FontSize/FontColor/Alignment`;表格支持位置、尺寸、列宽、表头/单元格颜色;图片支持 Base64/data URI、位置和尺寸。
|
|
68
|
+
|
|
69
|
+
<!-- /microi-progressive:chunk -->
|
|
70
|
+
<!-- microi-progressive:chunk id=v8-export-import-008 sha256=4dcd566dd9c5b38703831c67cc5cc2f2a99b0e7121fe2d2be2c068cfc8f739c3 -->
|
|
71
|
+
## 完整导入模式(含进度跟踪)
|
|
72
|
+
|
|
73
|
+
模块引擎【导入接口替换】+【导入进度接口替换】可实现实时进度提示。
|
|
74
|
+
|
|
75
|
+
### 导入接口(替换默认导入)
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
if (!V8.Param.TableId) {
|
|
79
|
+
return { Code: 0, Msg: '必须指定 TableId 标记当前导入哪张表' };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var importingKey = 'Microi:' + V8.OsClient + ':ImportTableDataStart:' + V8.Param.TableId;
|
|
83
|
+
var stepKey = 'Microi:' + V8.OsClient + ':ImportTableDataStep:' + V8.Param.TableId;
|
|
84
|
+
|
|
85
|
+
// 防止重复导入
|
|
86
|
+
if (V8.Cache.Get(importingKey) === '1') {
|
|
87
|
+
return { Code: 0, Msg: '有数据正在导入中,请稍后再试' };
|
|
88
|
+
}
|
|
89
|
+
V8.Cache.Set(importingKey, '1');
|
|
90
|
+
|
|
91
|
+
var stepList = [];
|
|
92
|
+
function pushStep(msg) {
|
|
93
|
+
stepList.push(DateNow('yyyy-MM-dd HH:mm:ss') + ':' + msg);
|
|
94
|
+
V8.Cache.Set(stepKey, JSON.stringify(stepList));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
pushStep('正在读取文件数据...');
|
|
98
|
+
|
|
99
|
+
// 解析 Excel
|
|
100
|
+
var base64 = Object.values(V8.FilesByteBase64)[0];
|
|
101
|
+
var parsed = V8.Office.ExcelToList({ FileByteBase64: base64, SheetIndex: 0 });
|
|
102
|
+
if (parsed.Code !== 1) {
|
|
103
|
+
V8.Cache.Set(importingKey, '0');
|
|
104
|
+
pushStep('文件解析失败:' + parsed.Msg);
|
|
105
|
+
return parsed;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
pushStep('已读取【' + parsed.Data.length + '】条数据');
|
|
109
|
+
pushStep('已导入【0】条数据...');
|
|
110
|
+
|
|
111
|
+
// 循环导入
|
|
112
|
+
for (var i = 0; i < parsed.Data.length; i++) {
|
|
113
|
+
var row = parsed.Data[i];
|
|
114
|
+
// 字段映射 / 校验
|
|
115
|
+
row.AAA = 111;
|
|
116
|
+
|
|
117
|
+
var addResult = V8.FormEngine.AddFormData(V8.Param.TableName, row, V8.DbTrans);
|
|
118
|
+
if (addResult.Code !== 1) {
|
|
119
|
+
V8.Cache.Set(importingKey, '0');
|
|
120
|
+
pushStep('导入第 ' + (i + 1) + ' 条出错:' + addResult.Msg + '(已回滚)');
|
|
121
|
+
return { Code: 0, Msg: addResult.Msg }; // 平台自动回滚事务
|
|
122
|
+
}
|
|
123
|
+
// 覆盖最后一条进度
|
|
124
|
+
stepList[stepList.length - 1] = DateNow('yyyy-MM-dd HH:mm:ss') + ':已导入【' + (i + 1) + '】条';
|
|
125
|
+
V8.Cache.Set(stepKey, JSON.stringify(stepList));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
pushStep('导入成功,已结束');
|
|
129
|
+
V8.Cache.Set(importingKey, '0');
|
|
130
|
+
return { Code: 1, Data: { Imported: parsed.Data.length } };
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 导入进度查询接口
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
if (!V8.Param.TableId) return { Code: 0, Msg: '需要 TableId' };
|
|
137
|
+
var stepStr = V8.Cache.Get('Microi:' + V8.OsClient + ':ImportTableDataStep:' + V8.Param.TableId);
|
|
138
|
+
return { Code: 1, Data: stepStr ? JSON.parse(stepStr) : [] };
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
<!-- /microi-progressive:chunk -->
|
|
142
|
+
<!-- microi-progressive:chunk id=v8-export-import-009 sha256=76d08b493419719094a95a5b760a83ae09b136bd54d66d2362efd428dea03ff8 -->
|
|
143
|
+
## 接收并下载文件(HTTP 链接转 Excel)
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
// 从 URL 下载图片插入 Excel 等场景
|
|
147
|
+
var resp = V8.Http.GetResponse({
|
|
148
|
+
Url: 'https://static.itdos.com/path/file.png'
|
|
149
|
+
});
|
|
150
|
+
var bytes = resp.RawBytes; // .NET byte[]
|
|
151
|
+
var base64 = System.Convert.ToBase64String(bytes);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
<!-- /microi-progressive:chunk -->
|
|
155
|
+
<!-- microi-progressive:chunk id=v8-export-import-010 sha256=0df463f76ba60100c087364b48dab1886d1315b093577ea9485471b34a7a3f6c -->
|
|
156
|
+
## 子表导入自动关联主表
|
|
157
|
+
|
|
158
|
+
当单独导入 `TableChild` 子表时,Excel 经常没有主表 Id,只带项目编号、客户名称等业务字段。默认导入引擎支持通过子表控件配置批量反查主表,并自动补齐子表外键。
|
|
159
|
+
|
|
160
|
+
本节只适用于“主表 1:N 子表”;单条独立记录关联应使用 `JoinForm`,不能把明细导入模型
|
|
161
|
+
设计成 `JoinForm`。在主表 `TableChild` 字段的 `Config` 中配置,其中子表、菜单和外键
|
|
162
|
+
位于 Config 根节点,导入选项位于 `Config.TableChild`:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"TableChildTableId": "子表 diy_table.Id",
|
|
167
|
+
"TableChildSysMenuId": "子表 sys_menu.Id",
|
|
168
|
+
"TableChildSysMenuName": "项目成品清单",
|
|
169
|
+
"TableChildFkFieldName": "XiangmuId",
|
|
170
|
+
"TableChild": {
|
|
171
|
+
"PrimaryTableFieldName": "Id",
|
|
172
|
+
"ImportAutoFillFk": true,
|
|
173
|
+
"FieldRelations": [
|
|
174
|
+
["Code", "XiangmuBM", true],
|
|
175
|
+
["Name", "XiangmuMC"]
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
配置含义:
|
|
182
|
+
|
|
183
|
+
- 根节点 `TableChildTableId` / `TableChildSysMenuId` / `TableChildFkFieldName` 必须是
|
|
184
|
+
回读后的真实子表、隐藏子菜单和子表物理外键,不能猜 Id,也不能放进内层
|
|
185
|
+
`Config.TableChild`。
|
|
186
|
+
- `ImportAutoFillFk`:是否在导入子表时自动补齐 Config 根节点指定的
|
|
187
|
+
`TableChildFkFieldName`;默认建议开启。
|
|
188
|
+
- `FieldRelations`:每项为 `[主表字段, 子表/Excel字段, 是否参与导入匹配]`。全部关系用于新增回写和导入回填;第三位为 `true` 的关系用于反查主表,多项为 `true` 时作为组合条件匹配。
|
|
189
|
+
- 不要把所有回填关系都标为 `true`。例如 Excel 只保证有项目编号时,`["Code","XiangmuBM",true]` 负责匹配,`["Name","XiangmuMC"]` 只在找到主表后补名称。
|
|
190
|
+
- 后端继续读取旧版 `ImportParentMatchFieldName` / `ImportChildMatchFieldName`、`ImportRelations`、`ImportBackfillFields` 和根节点 `TableChildCallbackField`;新版前端会合并去重为 `FieldRelations`,并在字段下次保存时清除旧键。
|
|
191
|
+
|
|
192
|
+
运行规则:
|
|
193
|
+
|
|
194
|
+
- 只有子表外键为空时才补齐;Excel 已传外键时不覆盖。
|
|
195
|
+
- `FieldRelations` 回填只有在子表对应字段为空时才写入;Excel 已传该字段值时不覆盖。
|
|
196
|
+
- 导入前按业务字段批量查询主表,避免逐行查询。
|
|
197
|
+
- 从主表表单内、左右树形页面或 `V8.OpenAnyTable` 带主表条件打开子表后导入时,即使 Excel 没有匹配字段,也可以通过固定主表 Id 查询主表并回填子表外键和全部 `FieldRelations`。
|
|
198
|
+
- 如果业务字段为空、主表找不到或匹配到多条主表,当前行不自动补齐,并写入导入进度/后台日志,避免错误关联。
|
|
199
|
+
- 示例:项目主表 `xiangmuguanli.Code` 匹配用料清单 `yongliaoqqingdan.XiangmuBM`,自动写入 `yongliaoqqingdan.XiangmuID`。
|
|
200
|
+
- 示例:项目主表 `xiangmuguanli.Name` 回填成品清单 `xiangmugoujianqd.XiangmuMC`,保证导入模板缺少项目名称列时列表仍显示正常。
|
|
201
|
+
|
|
202
|
+
<!-- /microi-progressive:chunk -->
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# v8-export-import 详细参考 3
|
|
2
|
+
|
|
3
|
+
> 按需读取;本文件由 SKILL.md 的原章节无损拆分。
|
|
4
|
+
|
|
5
|
+
<!-- microi-progressive:chunk id=v8-export-import-011 sha256=63cfa4a963d5c37e81c63f5c2b6b47a4709d1a0896d76e9feba4566d118cfe6b -->
|
|
6
|
+
## 安全 / 性能注意
|
|
7
|
+
|
|
8
|
+
- ❌ 不要在循环中逐条 `AddFormData` 而不传 `V8.DbTrans`:每条独立事务,性能差且部分失败会留脏数据
|
|
9
|
+
- ✅ 传 `V8.DbTrans` 让所有插入在同一事务,失败自动回滚
|
|
10
|
+
- ✅ 大文件(>1万行)建议拆批 `AddTableData` 批量插入
|
|
11
|
+
- ✅ 校验字段长度、类型、必填,防脏数据
|
|
12
|
+
- ✅ 接口引擎要返回文件,必须在配置中开启【响应文件】
|
|
13
|
+
- ✅ 进度 Key 用 `Microi:${V8.OsClient}:Category:Key` 命名,区分租户
|
|
14
|
+
|
|
15
|
+
### 复盘:应用包同步物理字段时直接 ALTER 导致安装异常
|
|
16
|
+
|
|
17
|
+
- 触发场景:目标租户安装或升级应用包时,已有长文本配置超过来源包的 `varchar(N)` 长度,或历史数值字段仍以空字符串保存,`MODIFY COLUMN` 分别报 `Data too long`、`Incorrect integer value: ''`。
|
|
18
|
+
- 根因:导入器把来源库物理字段定义直接覆盖到目标库,没有判断是否属于缩窄变更,也没有在文本转数值前兼容平台历史空值。
|
|
19
|
+
- 通用规则:物理字段同步必须只扩宽、不缩窄;目标库已有更宽文本类型或更大整数类型时保留目标类型。文本转数值前仅可把空字符串规范为 `NULL`,发现非空非数字值必须中止该字段迁移并报告数量,禁止静默转为 `0` 或截断数据。只要导入日志存在异常,就不得写入“安装成功”的应用版本记录。
|
|
20
|
+
- 自动化检查:准备“超长 JSON + 空字符串数值 + 非数字脏值”三类旧库样本,重复安装同一应用包;前两类应无异常且数据不丢失,第三类应明确失败且原数据保持不变。
|
|
21
|
+
|
|
22
|
+
### 复盘:重复字段与业务 Key 改名破坏应用包幂等安装
|
|
23
|
+
|
|
24
|
+
- 触发场景:应用包中同一张表出现两个同名字段时,第一次 `ADD COLUMN` 成功、第二次报 `Duplicate column name`;在线应用保留原 Id 但修改 `AppKey/MsKey` 后,目标库按新 Key 查不到记录,又用原 Id 执行 INSERT,报主键重复。
|
|
25
|
+
- 根因:安装器只在阶段开始时读取一次物理字段快照,新增后没有更新;同时只按业务 Key 判断在线应用是否存在,没有优先按稳定 Id 对齐,也没有迁移旧 Key 关联的微服务和页面。
|
|
26
|
+
- 通用规则:包内字段必须按 `TableId + lower(Name)` 去重,新增物理列后立刻更新内存快照;并发或历史残留造成的重复列错误需回查后按幂等跳过。在线应用、微服务及版本数据必须先按 Id、再按业务 Key 查找;Id 命中而 Key 变化时更新原记录并沿用原 Id,把关联页面统一迁移到新 Key,禁止再次 INSERT。
|
|
27
|
+
- 自动化检查:构造“同表重复字段”和“固定 AppId、AppKey 从 old-key 改为 new-key”两个包,连续安装至少两次;每次都应 `Code=1`,物理列、应用、微服务均只有一条,所有页面引用新 Key 且保留原关联 Id。
|
|
28
|
+
|
|
29
|
+
### 复盘:租户历史残留绕过 FormEngine 查询后触发主键和重命名冲突
|
|
30
|
+
|
|
31
|
+
- 触发场景:同一应用包在平台主租户、平台子租户和客户独立部署中表现不同;字段导入报 `diy_field.PRIMARY` 重复,字段改名报目标物理列已存在,旧版微服务包还可能调用不存在的 ZIP 哈希函数。
|
|
32
|
+
- 根因:导入器只用 FormEngine 判断记录是否存在,软删除、空 OsClient 或历史异常记录会被过滤,但物理主键仍在;字段重命名只判断元数据变化,没有在 DDL 前分别检查源列和目标列;修复只写入某个租户接口引擎,没有让全局升级器按导入器能力重新刷新。
|
|
33
|
+
- 通用规则:元数据 UPSERT 必须在 FormEngine 未命中时直查物理主键;同一逻辑字段应恢复后更新,真正的 Id 冲突应生成目标 Id 并建立包内引用映射。执行 `CHANGE COLUMN` 前必须检查源列存在且目标列不存在,目标列已存在时按幂等跳过。导入器修复必须同时更新官方资源、目标租户和自动升级能力检测,禁止只依赖全局版本号。
|
|
34
|
+
- 自动化检查:准备软删除主键、空租户主键、同表目标列已存在、旧导入器函数缺失四类租户快照;连续安装系统设置、首页数据包和含源码 ZIP 的微服务包两次,均应 `Code=1` 且版本记录只反映无异常安装。再把全局版本号设为高于修复版本、导入器降级,验证启动升级仍会按能力标记自动恢复导入器且不降低全局版本号。
|
|
35
|
+
|
|
36
|
+
### 复盘:数据库空库导出日期区域化且导入器吞错导致延迟误报
|
|
37
|
+
|
|
38
|
+
- 触发场景:空库 SQL 把 MySQL `datetime` 导出成 `05/12/2026 12:50:33` 等区域格式;导入器逐句执行时跳过或吞掉失败语句,后续初始化才误报“缺少默认 admin 用户”。
|
|
39
|
+
- 根因:导出器只按 CLR 返回类型格式化,没有以 `information_schema.COLUMNS.DATA_TYPE` 为事实源;导入器把局部失败计数后仍返回成功,也没有在导入结束立即校验核心表和模板账号。
|
|
40
|
+
- 通用规则:数据库转储必须按真实物理列类型格式化 `date/datetime/timestamp`,统一输出 ISO 日期;完整 SQL 导入任一语句失败必须整体失败并保留原始数据库错误,禁止吞错继续。导入完成后立即校验核心表和模板账号,后端读取最新发布包时优先直读对象存储,避免 CDN 长缓存返回旧包。
|
|
41
|
+
- 自动化检查:制作并发布空库后校验 ZIP 哈希、SQL 中区域日期匹配数为 0、核心表和默认 `admin` 存在;再从真实注册页创建新租户,并使用新租户 `admin` 的初始密码登录一次,不能只验证发布任务或租户记录返回成功。
|
|
42
|
+
<!-- /microi-progressive:chunk -->
|