@microi.net/cli 4.9.9 → 5.0.1

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.
@@ -103,7 +103,7 @@ await V8.Notification.MarkRead({ All: true });
103
103
 
104
104
  ## 应用商城交付
105
105
 
106
- “消息通知”应用包至少包含三张业务表、相关菜单、`msg_event`、`msg_internal_list`、`msg_internal_mark_read` 和必要索引。包内不得包含真实公众号 Token/AppSecret、用户接收人、OpenId、历史发送记录或租户专属 URL。先 `ValidateOnly`,再在获准的目标租户安装并回读;结构校验不能替代真实安装验收。
106
+ “消息通知”应用包必须包含 `mic_msgset`、`mic_msg_event_log`、`wx_tpl_msg`、`wx_mp`、`wx_mini_program` 五张结构资源,以及相关菜单、`msg_event`、`msg_internal_list`、`msg_internal_mark_read` 和必要索引。`wx_mp`、`wx_mini_program` 只交付物理表结构与表单字段元数据,不得携带数据集;否则既可能泄露真实公众号/小程序密钥,也会覆盖目标租户配置。`sys_user.WxMpId` 和 `wx_tpl_msg` 会读取 `wx_mp`,漏包会使 `/system/diy-user` 等无关页面在加载 Select 数据源时触发 `GetDiyFieldSqlData` 缺表错误。包内不得包含真实公众号 Token/AppSecret、用户接收人、OpenId、历史发送记录或租户专属 URL。先 `ValidateOnly`,再在全新或缺表目标租户真实安装,回读五张表、应用版本和依赖页面;结构校验不能替代真实安装验收。
107
107
 
108
108
  ## 最低验收
109
109
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: microi-client-frontend
3
- description: Microi.Client 源码架构指南。用于修改 Microi.Client Vue 前端代码,尤其是表单引擎、diy-table、diy-form-full、工作流面板、sys_menu 按钮、前端 V8 事件、路由以及页面/弹窗/抽屉行为。
3
+ description: Microi.Client 源码架构指南。用于修改 Microi.Client Vue 前端代码,尤其是表单引擎、diy-table、diy-form-full、工作流面板、sys_menu 按钮、前端 V8 事件、路由、微服务宿主 keep-alive/TagsView 缓存/白屏恢复,以及页面、弹窗和抽屉行为。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
@@ -2,13 +2,19 @@
2
2
 
3
3
  > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
4
 
5
- <!-- microi-progressive:chunk id=microi-client-frontend-011 sha256=18261b2eb8de007296bc536802abaf995f0696fd44c54677e0f7141dcef3c5ca -->
5
+ <!-- microi-progressive:chunk id=microi-client-frontend-011 sha256=26acb7297e2d0e794ae447beaba3b19171f9f232255adafc26966187e445e95a -->
6
6
  ## Vue3 前端微服务宿主规则
7
7
 
8
8
  `sys_menu.OpenType=MicroService` 时,动态路由必须把 `MicroServiceId`、`MicroServicePageId`、`MicroServiceRoutePath` 和真实入口 `MicroAppUrl` 写入 route meta;浏览器侧菜单路由使用 `/#/micro-app/{MsKey}/{RoutePath}`,不要再生成 `/micro-app-host/{menuId}`,否则地址过长且刷新或直接访问菜单路由容易加载空白页。
9
9
 
10
10
  同一个编译后的微服务可以绑定多个后台菜单和内部页面。`MicroAppHost` 的 `<micro-app name>` 必须包含菜单 Id、路由路径或其它实例维度,避免多个菜单共享同一个 appKey 时触发 `app name conflict`。入口 URL 中的 `microRoute/routePath` 只用于解析,最终应通过 `data.microRoute` 传给子应用,入口文件 URL 保持稳定。
11
11
 
12
+ 菜单微服务的缓存所有权固定为一层:动态菜单和友好路由都设置 `meta.keepAlive=false`、`meta.microAppHost=true`,`AppMain` 不缓存 Vue 宿主;`host.vue` 的 `<micro-app keep-alive>` 才保存子应用 DOM、路由和状态。`AppMain` 对菜单微服务使用 `$route.fullPath` 作为宿主 key,宿主创建时立即快照 path/fullPath/meta/query,之后不得监听全局 `$route` 去改写即将隐藏的旧宿主。普通 Vue 页面继续使用原有 `KeepAlive`,菜单微服务也不得占用或淘汰 `cachedViews` 槽位。
13
+
14
+ 运行时缓存集中维护在 `utils/microAppRuntimeCache.js`:实例名必须由租户、AppKey、菜单、fullPath、版本和入口的安全指纹稳定生成,长度受限且不暴露 Token/查询原文;全局最多保留 5 个实例,只淘汰最久未使用的 hidden 实例。TagsView 的关闭当前/其它/全部和访问记录淘汰必须按 fullPath 精确销毁;退出登录、Token 重置、角色切换必须清空全部;同一路由版本/入口变化必须替换旧实例。销毁统一调用 `unmountApp(name,{destroy:true,clearData:true})`,不能只从本地 Map 删除。
15
+
16
+ 宿主监听 `beforeshow/aftershow/afterhidden`:恢复时用 `forceSetData` 下发最新 Token、OsClient、权限、主题、路由和视口,并重新执行可见 DOM 健康检查;隐藏时停止宿主看门狗并把实例放入 LRU。`microAppData.cache` 与 `hostCapabilities.lifecycle` 要公开缓存模式、所有者、上限和 `appstate-change` 状态,错误诊断同时显示 cacheMode/cacheState/cacheInstance。可见 DOM 不健康时只自动销毁重建一次,禁止恢复阶段无限重试。
17
+
12
18
  菜单型微服务的宿主操作集中维护在 `views/micro-app/host-bridge.js` 和 `host.vue`。
13
19
  `microAppData.hostCapabilities` 必须下发 `microi.host.v1` 协议、`tab` 模式、请求/结果事件名和动作清单;
14
20
  子应用只允许 dispatch `micro-app:host-action`,不能接收父页面函数或直接操作 TagsView/Router。
@@ -64,7 +70,7 @@ VS Code 插件执行前端微服务构建前必须先安全清理当前项目自
64
70
  - `routes` 是页面源码、`microi.routes.json`、发布路由和菜单绑定的共同事实源;一条路由只生成一个页面文件,必须明确 `path/name/title/sourceFile/isHome`。不能为了提供默认首页额外生成一个未被需求或菜单使用的第三页面。
65
71
  - 脚手架完成后依次执行:`npm install`、本地构建、`microi_create_microservice`、`microi_sync_microservice_source`、`microi_publish_application_directory_stream`。真实编译目录优先流式发布;只有当前服务器尚未部署流式端点且产物很小时,才允许临时使用兼容的 `microi_publish_microservice`,并在交付结论中如实注明。
66
72
  - 发布回读取得 `sys_microiservice.Id` 与每条 `sys_microiservice_page.Id` 后,使用 `microi_create_module` 一次传入 `openType=MicroService`、`microServiceId`、`microServicePageId`、`microServiceRoutePath`、`microServiceKey`。菜单工具必须写后回读这些字段;不得长期依赖“先建普通 URL 菜单,再手工补字段”的两步绕路。
67
- - 最终通过 `microi_get_application_context`、`microi_get_microservice`、`microi_get_module` 和真实登录后的两个友好菜单路由逐层验收;连续切换两个菜单,检查页面标题、MicroApp 上下文、Vue 交互、无 404/5xx/白屏/实例冲突,并保存 fullPage 截图后用 `view_image` 复核。
73
+ - 最终通过 `microi_get_application_context`、`microi_get_microservice`、`microi_get_module` 和真实登录后的友好菜单路由逐层验收;多个菜单至少往返切换 8 轮,检查标题与子路由不串页、缓存范围内输入/筛选/滚动保持、无 404/5xx/白屏/永久骨架屏/实例冲突。再打开第 6 个实例验证 LRU 冷启动,并关闭 Tab/退出登录验证精确销毁;保存 fullPage 截图后用 `view_image` 复核。
68
74
 
69
75
  ### 表单下拉 Data 动态对象选项
70
76
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: microi-microservice
3
- description: Microi 前端微服务 MicroService 开发与交付指南。用于创建、读取、修改、构建、发布或修复 Vue3 微应用,维护 microi.routes.json,绑定 sys_menu,使用 V8.OpenAppDialog,或通过 MCP 管理 Web、UniApp、MicroService 应用源码和运行时。
3
+ description: Microi 前端微服务 MicroService 开发与交付指南。用于创建、读取、修改、构建、发布或修复 Vue3 微应用,维护 microi.routes.json,绑定 sys_menu,使用 V8.OpenAppDialog,处理菜单页签 keep-alive、appstate-change、状态保留、滚动条、骨架屏或白屏,或通过 MCP 管理 Web、UniApp、MicroService 应用源码和运行时。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
@@ -159,6 +159,24 @@ AI 生成菜单微服务时,应优先封装一个 `callMicroiHost(action, data
159
159
  放在右侧内容容器内,使微服务导航栏和顶部栏保持挂载;浏览器 `popstate/hashchange` 要能恢复
160
160
  内部路由。只有确实要离开当前微服务、打开另一个吾码后台菜单或替换顶部 Tab 时才调用宿主路由动作。
161
161
 
162
+ ### 菜单页签缓存与子应用生命周期(强制)
163
+
164
+ - 菜单微服务只有一个缓存所有者:Vue 路由宿主固定 `meta.keepAlive=false`,`<micro-app keep-alive>` 独占子应用状态。禁止把外层 Vue `KeepAlive` 打开,也禁止子应用通过随机实例名规避运行时缓存;双层缓存会产生旧宿主与当前路由竞争、无数据、永久骨架屏和白屏。
165
+ - 每个主框架 `fullPath` 使用稳定且不泄露查询参数/Token 的实例指纹。平台最多保留 5 个菜单运行时,超过后按 LRU 销毁最久未使用的隐藏实例;Tab 仍保留,再次进入允许冷启动。关闭当前/其它/全部 Tab、访问记录淘汰、退出登录、Token 重置、角色变化、同路由版本或入口变化时必须精确 `unmountApp(name,{destroy:true,clearData:true})`。
166
+ - 恢复隐藏实例时,宿主用 `forceSetData` 同步当前 Token、OsClient、权限、主题、路由和视口,再复核 `micro-app-body/#app` 的真实可见 DOM;失败只允许自动销毁重建一次。`hostCapabilities.lifecycle` 暴露 `cacheOwner=micro-app`、`cacheMode=runtime-keep-alive`、`maxCachedTabs=5` 和状态事件。
167
+ - AI 创建或修改菜单微服务时必须生成 `appstate-change` 适配:`afterhidden` 幂等暂停轮询、WebSocket、观察器和昂贵任务;`aftershow` 重新读取宿主数据、幂等恢复任务并在下一帧重算图表/虚拟列表。隐藏时保留表单输入、筛选、滚动与内部路由,禁止清空业务状态;弹窗和表单嵌入不套用菜单页签保活。
168
+
169
+ ```js
170
+ window.addEventListener('appstate-change', (event) => {
171
+ if (event.detail?.appState === 'afterhidden') pauseBackgroundWork();
172
+ if (event.detail?.appState === 'aftershow') {
173
+ configureMicroiV8(getMicroiContext());
174
+ resumeBackgroundWorkOnce();
175
+ requestAnimationFrame(resizeChartsAndVirtualLists);
176
+ }
177
+ });
178
+ ```
179
+
162
180
  微服务所有主题变量、reset、通用元素规则必须限定在 AppKey 唯一根容器(推荐
163
181
  `[data-mci-ui-root="{AppKey}"]`)下,不能只用宿主也会命中的裸 `[data-mci-ui-root]`;禁止用
164
182
  `:root/html/body/#app`、裸 `*`、裸 `button/input` 污染宿主。
@@ -202,7 +220,8 @@ AI 生成菜单微服务时,应优先封装一个 `callMicroiHost(action, data
202
220
 
203
221
  - 源码、构建文件、运行时、页面路由和菜单五层分别回读。
204
222
  - 组合发布成功前,私有源码回读必须与本地源码在路径集合、文件数、字节数、逐文件 SHA-256 和规范化清单哈希上完全一致;任何缺失、多余或读取错误都要阻止运行版本切换。
205
- - 直接刷新友好路由与连续切换多个微应用不 404、白屏或实例名冲突。
223
+ - 直接刷新友好路由与多个菜单至少往返 8 轮不 404、白屏、永久骨架屏、串页或实例名冲突;缓存范围内输入/筛选/滚动/内部路由保持。
224
+ - 打开第 6 个菜单实例后确认 LRU 只淘汰最旧隐藏实例且重入可冷启动;关闭 Tab、关闭其它/全部与退出登录后确认对应运行时已销毁。
206
225
  - Dialog/Drawer 成功、取消、错误和关闭协议正确。
207
226
  - 表单 `DevComponentPath` 能匹配页面 `LegacyComponentPaths`,指定路由正常加载;Add/Edit/View/只读、字段值回写和自动高度均通过。
208
227
  - 独立地址覆盖“已有 Token 自动进入”和“无 Token 显示帐号密码”;`EnableCaptcha` 开/关各验一次,验证码响应头和登录参数正确。
@@ -157,7 +157,7 @@ const host = window.microApp?.getData?.() || {};
157
157
 
158
158
  常见字段:`apiBase`、`osClient`、`token`、`menuId`、`moduleEngineKey`、`diyTableId`、
159
159
  `permissionContext`、`appKey`、`version`、`microRoute`、`dialog`、`dialogData`、
160
- `componentMode`、`componentData`。只在内存中使用 Token。
160
+ `componentMode`、`componentData`、`cache`、`hostCapabilities.lifecycle`。只在内存中使用 Token。
161
161
 
162
162
  独立访问时没有宿主 Token:先配置清单中的 `apiBase/osClient`,读取 `V8.GetSysConfig(true)`,
163
163
  没有有效本地 Token 才显示吾码帐号密码登录;按 `EnableCaptcha` 动态请求验证码并向 `V8.Login`
@@ -175,6 +175,31 @@ const host = window.microApp?.getData?.() || {};
175
175
  sticky/虚拟列表时,子应用以宿主可用高度约束自己的滚动容器并设置 `overflow-y:auto`,框架边界
176
176
  因不再发生内容溢出而不显示滚动条。不要同时让宿主外层、微服务边界和自动高度根节点都承担滚动。
177
177
 
178
+ 菜单页签还采用单一缓存所有者:主框架 Vue 宿主不进入 `KeepAlive`,由 `<micro-app keep-alive>`
179
+ 保存子应用状态。宿主按租户、AppKey、菜单、主框架 `fullPath`、版本和入口生成稳定指纹,最多保留
180
+ 5 个运行时;超过上限时只按 LRU 销毁隐藏实例。关闭当前/其它/全部 Tab、访问记录淘汰、退出登录、
181
+ Token 重置、角色变化、同一路由版本或入口变化时,使用 `destroy:true,clearData:true` 精确销毁。
182
+ 弹窗和表单组件不承诺页签缓存,禁止套用菜单规则。
183
+
184
+ 隐藏/恢复由子应用原生事件通知:
185
+
186
+ ```javascript
187
+ window.addEventListener('appstate-change', function (event) {
188
+ var state = event.detail && event.detail.appState;
189
+ if (state === 'afterhidden') pauseBackgroundWork();
190
+ if (state === 'aftershow') {
191
+ configureMicroiV8(getMicroiContext());
192
+ resumeBackgroundWorkOnce();
193
+ requestAnimationFrame(resizeChartsAndVirtualLists);
194
+ }
195
+ });
196
+ ```
197
+
198
+ `pause/resume` 必须幂等,分别处理轮询、WebSocket、观察器、图表和虚拟列表;隐藏时不得清空用户
199
+ 输入、筛选、滚动或内部路由。恢复时宿主会以 `host:resume` 强制同步当前 Token、OsClient、权限、
200
+ 主题、路由和视口,然后复核真实可见 DOM;子应用也应重新读取宿主上下文。AI 生成菜单微服务时
201
+ 必须包含此生命周期适配,不能只实现首次 `mount`。
202
+
178
203
  子应用通过模板 SDK 调用接口,不自行发明认证协议。关闭/结果使用宿主约定的
179
204
  success、cancel、error/close 事件;业务写入成功后再报告 success。
180
205
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: playwright-e2e
3
- description: 按 Microi 系统真实业务逻辑进行 Playwright 全自动化、全面测试。用于测试 PC Vue、uni-app H5、网站、界面引擎、移动商城、ApiEngine/FormEngine 契约、登录流程、写入闭环、网络防护、截图、报告和 Playwright Test for VSCode 集成。
3
+ description: 按 Microi 系统真实业务逻辑进行 Playwright 全自动化、全面测试。用于测试 PC Vue、前端微服务菜单切换与 keep-alive/LRU、uni-app H5、网站、界面引擎、移动商城、ApiEngine/FormEngine 契约、登录流程、写入闭环、网络防护、截图、报告和 Playwright Test for VSCode 集成。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
@@ -46,12 +46,14 @@ jobs:
46
46
  | 页面有横向滚动 | 组件撑出视口 | 对根容器和列表容器加 `max-width:100vw; overflow-x:hidden` |
47
47
 
48
48
  <!-- /microi-progressive:chunk -->
49
- <!-- microi-progressive:chunk id=playwright-e2e-025 sha256=2ae146b962ec19d0f74f9228ccfdb2d67164dea441dccce4dcc68a867269131a -->
49
+ <!-- microi-progressive:chunk id=playwright-e2e-025 sha256=be071153d695081b7c20d34cb5e9563480e3f09d9cd0292f2ca4b0245438787b -->
50
50
  ## 前端微服务 E2E 必测点
51
51
 
52
52
  测试 Vue3 MicroApp 微服务时,不能只验证 `/micro-app/{OsClient}/{appKey}/index.html` 或带 token 的临时 URL。必须先建立真实登录态,再访问用户实际使用的不带 token 菜单路由,例如 `/#/micro-app/{MsKey}/{RoutePath}`,并确认地址栏没有退回旧的 `micro-app-host` 长地址。
53
53
 
54
- 同一套微服务绑定多个菜单时,至少连续访问两个菜单页面,断言没有 `element head is missing`、`Failed to fetch`、`ERR_TOO_MANY_REDIRECTS`、`app name conflict` micro-app 错误。
54
+ 同一套微服务绑定多个菜单时,至少选择 3 个真实菜单往返切换 8 轮,逐轮断言主框架 route、当前菜单和子应用可见内容匹配,且没有 `element head is missing`、`Failed to fetch`、`ERR_TOO_MANY_REDIRECTS`、`app name conflict`、永久骨架屏或空白内容。不能只断言 `<micro-app>` 元素存在。
55
+
56
+ 页签缓存验收必须覆盖单一所有者与清理边界:在一个缓存范围内修改表单输入、筛选、内部路由或滚动位置,切走再返回后状态应保持;连续打开 6 个菜单微服务实例,断言运行时最多保留 5 个,最久未使用的隐藏实例重入时正常冷启动;关闭当前/其它/全部 Tab 后对应实例消失,退出登录后全部实例清空。恢复页还要断言收到最新 Token/OsClient/权限/主题/视口上下文,且任一时刻只有一个可见活动微服务。若子应用有轮询或 WebSocket,记录 `appstate-change`,确认 `afterhidden` 暂停、`aftershow` 幂等恢复而没有重复连接。
55
57
 
56
58
  如果页面内提供 Microi SDK 调用按钮,必须点击并断言返回 `Code=1`,同时确认没有 `登录身份已过期`、`1001`、`1002`。只看到标题文本不代表鉴权链路通过。
57
59