🏪 应用商城
平台从 v4.7.2 开始自动安装应用商城模块,用户可通过应用商城安装和管理各种应用
📸 预览图

数据来源
AI 应用与应用商城已经统一为一个系统,sys_microistore 是唯一应用主表。商城入口在同一个页面保留四个业务页签:
| 页签 | 数据来源 |
|---|---|
| 应用市场 | 读取当前选中的联邦商城源,包含平台应用、Web、UniApp、微服务以及租户发布的公开/私有应用。 |
| 已经安装应用 | 以当前租户 sys_microistoreversion 为安装事实源,显示安装版本、最新版本和更新状态。 |
| 发布 / 制作离线包 | 只读取当前登录用户在当前租户拥有的应用,草稿和构建失败项也可继续编辑。 |
| 安装离线包 | 在当前页面校验并提交后台安装任务,不跳转到另一个菜单。 |
旧的 /microi-store-installed、/microi-store-published 菜单不再作为独立入口。主页面保留来源、筛选和分页上下文,并通过应用包中的受管接口引擎读取列表、详情与历史版本。列表可按 ApplicationType、Category、PublisherType、公开范围和关键词筛选。
统一字段约定:
| 字段 | 说明 |
|---|---|
ApplicationType | 运行形态:Regular / Platform / Web / UniApp / MicroService。Regular 是普通平台离线包的新建默认值;商城中的既有平台应用、平台应用通知和旧包仍使用 Platform,两者都必须兼容,不能在未迁移数据和调用方前强制改单值。 |
AppType | 历史兼容字段,旧数据/接口曾同时把它用于“官方/社区来源”和运行形态。新代码不得以它作为唯一判断依据;读取旧包时可回退,写入新数据使用 ApplicationType + PublisherType。 |
Category | 游戏、企业应用、办公、教育、行业应用、平台能力等。 |
PublisherType | 发布者身份/展示来源:官方应用、社区应用。新代码的官方/社区筛选以此字段为准。 |
IsPublic | 1 为公开应用,未登录商城源也可读取;0 为私有应用,只在来源登录成功后可见。历史空值按公开兼容。 |
ViewCount | 官网或商城打开应用时累计浏览次数。 |
InstallCount | 每次安装、更新或重新安装成功后累计一次;后台任务重试仍使用同一个 OperationId,不会重复累计。 |
当前租户数据只走当前 ApiBase + OsClient + Token;只有用户主动选择其它商城源时,才由可信后端代理向该来源发起只读查询或取包请求,来源 Token 不经过浏览器。
商城来源与私有应用
商城来源使用 ApiBase + OsClient 唯一定位。添加来源时先识别系统标题、验证码策略以及公开应用数;未登录时只能安装公开应用,登录后才可统计和安装该账号有权访问的私有应用。每个主租户、子租户都可以发布公开或私有应用,也可以添加其它吾码平台作为来源。
来源帐号密码只参与当次登录,不会保存。平台用非 PC 的 MCP/Mobile 客户端类型签发长会话 Token,并在当前租户后端加密保存到 mci_system_setting;浏览器、来源配置 JSON、日志和应用包都拿不到 Token。来源代理固定校验保存时的 ApiBase、OsClient 和有效期,退出来源登录会删除密文。
应用详情显示完整业务信息和可安装版本。当前版本与 mic_data_version 中仍保留旧包正文或已验证 HDFS 包指针的历史快照都可选择安装;后台任务保存实际选择的版本,允许在新版出现问题时明确重新安装旧版。版本区使用服务端搜索与分页,当前版本固定置顶,默认每页不超过 20 条,不能一次加载全部历史版本再由浏览器过滤。详情弹层使用宿主级固定毛玻璃遮罩,默认居中;标题栏拖动和窗口缩放后都会按弹层真实宽高限制四边,内容不能移出视口。平台官方发布节点仅显示“平台官方应用源”标记,不允许对自身执行安装、更新或重新安装。
组合包中的运行应用身份
普通应用包可以用 ApplicationBundles 携带独立微服务工作台,公开商品仍保持原来的 PackageInfo.AppId;嵌套运行应用使用自己的 Application.AppId/AppKey。发布器从源应用 当前记录携带 IsPublic/IsApprove,请求参数不能替代这两个源标记。
| 运行应用声明 | 安装行为 |
|---|---|
显式 IsPublic=0 | 首装和重装均保持私有;目标 Switch 默认值不能把它公开。 |
显式 IsPublic=1 | 按源声明公开运行应用。源码下载仍单独校验当前拥有者或超级管理员权限。 |
历史包没有 IsPublic | 已有目标保持原公开范围;首次新增运行应用明确为私有。 |
显式 IsApprove=0 | 保留源未审批状态,构建成功不会把它改成已审批。历史包未声明时保留原审批兼容行为。 |
声明只接受数字 0/1、字符串 "0"/"1" 和布尔值;null、"false"、空字符串或其它类型 都会停止安装。直接传入的包在任何数据库或文件操作前检查,下载包在读取正文后、写入该包资源前检查。 升级至包含此协议的应用商城包后,旧组合包第一次安装也会采用私有默认值;已有目标不被自动改成私有。
{"ApplicationBundles":[{"Application":{"AppId":"mci-party","AppKey":"mci-party","IsPublic":0,"IsApprove":0}}]}安装包存储与数据库容量
新版商城不再把数 MB 的 JSON 包长期放在 sys_microistore.AppPakcet,也不会让每次数据版本快照在 mic_data_version.Data 中复制同一份正文:
| 应用范围 | 包存储 | 下载方式 |
|---|---|---|
| 公开应用 | HDFS 公有桶,PackageStorageMode=HdfsPublic | 来源 FileServer/CDN 公有地址;下载后仍校验大小与 SHA-256。 |
| 私有应用 | HDFS 私有桶,PackageStorageMode=HdfsPrivate | 由来源后端验证登录身份后签发短期地址;Token 和签名地址不落浏览器配置或日志。 |
数据库只保留 PackageId、PackageHdfsPath、PackageSha256、PackageSize、内容类型、格式版本和校验时间。发布器先上传 UTF-8 JSON,再从 HDFS 回读并核对字节数和 SHA-256,全部一致后才更新商城指针并清空内联正文;安装器会独立下载和校验,不能只相信数据库或 Redis。历史版本继续以不可变 StoreVersionId 精确安装,快照保存同一组指针,不会静默换成当前版本。
制包时,全局 v3 运行对象不能通过租户私有 HDFS 代理跨目录读取。发布器从应用当前 CommittedPublishVersionId 精确核对所属应用的 Completed 版本、运行清单哈希与请求指纹, 再检查每个对象的租户、应用、版本、请求目录、文件相对路径、大小和 SHA-256。验证通过后, 由当前后端配置的 API origin 构造 v3 运行文件读取地址,兼容仅保存普通 CDN 地址的微服务 投影;不会信任请求参数或文件记录提供的外部域名,也不会改用最新 staged 版本。 读取关闭自动重定向,只接受 HTTP 200;已有 ETag 必须与清单 SHA-256 一致。解压后的文本 Content 和二进制 RawBytes 都要按真实字节验证大小及 SHA-256。任一验证失败即停止制包, 不能仅凭 HTTP 成功、同长度或 CDN 页面能打开继续发布。
历史数据库若在 V3 发布协议之前已经写入 mci_ai_app_file,这些文件可能没有 VersionId。升级程序会先按租户和 AppId 创建确定性的 legacy-unversioned-v3 只读归档版本,把原文件绑定后强回读空值为零,再创建版本/路径唯一索引;不会合并或删除文件。文件同时缺少 AppId、确定性 Id 冲突或同名版本身份不一致时,升级会输出数量与样本 Id 后停止,避免猜错归属。
应用商城列表的正式公开地址是 /apiengine/get-microi-store-list,接口 Key 仍为 get-microi-store。为兼容尚未完成应用更新的旧批量工作器,官方应用商城包同时提供 /apiengine/get-microi-store Managed 兼容入口,并只转发到正式列表接口;新代码不得继续使用旧地址。
旧库可由超级管理员运行应用商城包提供的容量治理后台任务。任务先自愈缺失字段,再以有界 Id 游标分批外置 sys_microistore 和商城相关 mic_data_version 快照;每行都在 HDFS 校验成功后以原值 CAS 清理,因此节点重启、重试或并发修改不会误删。任务不会对数 GB 的历史 JSON 执行全表 LIKE,也不会自动运行可能长时间锁表的 OPTIMIZE TABLE。逻辑正文清空后,如需让 MySQL 物理文件立即缩小,应在完成备份的维护窗口由数据库管理员另行评估执行。
发布器 v2.1.2 修复受管接口更新后的重复发布摘要漂移:源码、Managed 策略和所有权均与已发布包相同时,保留该包的有效基线;真正的源码变更仍推进基线并保留历史兼容摘要。缺失或无效基线从实际旧源码重新建立,CreateIfMissing 租户 Hook 保持原策略。Inspect 与 Publish 必须使用相同的冻结 PreparedAssets 和资源选择,并在发布后立即重放原请求,独立核对包 SHA-256、字节数和不可变快照 Id;重放被 CAS 拒绝仍算失败,不能仅以首次成功声称幂等。
共享表的稀疏字段选集
应用只扩展已有共享表的少数字段时,标准导出器和 ai_app_publish_store 接收 SparseTableSelections: [{ TableId, FieldIds }]。Id 必须来自当前租户权威元数据, 最多 32 张表、每表 512 个非重复字段;不接受调用方传表正文、DDL 或布局覆盖。 同一表不能同时进入完整 TableIds 与稀疏选集,安装基础设施表不能被裁剪。
导出只保留表 Id/Name、所选字段和对应物理列;不携带共享 Tabs/Column、 其它字段、建表或索引。数据只允许 InsertIfMissing,行与冲突字段必须在选集中。 没有数据行的共享表自动生成标准零行 DataSet,复用安装前置检查:缺物理表或 共享表元数据时,在资源写入前失败;不是自动安装依赖,也不是空库建表契约。
旧导入器会拒绝受保护共享表的零行 DataSet。须先升级包含 EMPTY_SHARED_TABLE_PREREQUISITE_V1 的商城安装器,再安装混合应用。 新分支仅接受严格零行形状,不给受保护表业务数据增加写权限。 普通 DataSet 仍要求完整建表资源,不能借稀疏分支绕过结构闭包。
导出器 v1.3.8 修复稀疏默认数据的序列化形状:未声明实际父绑定时, 必须完全省略 ParentBinding 键,不能用 undefined 让宿主转成 null; 普通配置子表的显式绑定保持原契约,稀疏导入安全门不放宽。 仅保留稀疏选集中字段在源记录上真实存在的空字符串;NULL、缺失字段、 未选字段不推断默认值,跨租户与隐藏元数据仍排除,普通全表导出保持旧行为。 数值 0 原本就保留;秘密状态必须经已有可信设置入口规范源数据, 不能由导出参数或包正文合成。升级后重新 Inspect 并冻结新摘要,旧快照不可改写。
安装器 v3.0.5 同时执行 SPARSE_TABLE_IMPORT_PREFLIGHT_V2:直接传包和下载包均在进度持久化、物理兼容自举及资源写入前核验原始稀疏正文和目标。严格零行依赖不能由同包 CREATE 自行满足;带默认数据的稀疏表也必须已有实体表及唯一未删除的表单元数据。MySQL/SQL Server 查询要求 BASE TABLE,Oracle 使用 USER_TABLES。共享表只接受 Id/Name、精确字段与物理列及 InsertIfMissing 数据,不接受布局、其它字段、字段退役或该表 DDL;非空数据集可保留标准导出的 TableDescription,该描述不授权更新共享表布局。
DECLARATIVE_PACKAGE_DDL_PREFLIGHT_V1 在同一写前门禁逐字符识别引号和注释,按实际 SQL 目标核对声明表名,只接受受支持的 CREATE TABLE、CREATE INDEX 与列/索引 ALTER TABLE。DML、动态执行、多语句、未知声明、MySQL/MariaDB 可执行注释及提示一律拒绝。字符串内部的分号和普通注释可保留;含反斜杠的引号内容因 SQL mode/方言歧义拒绝,改用 SQL 标准重复引号。现有官方包 DDL 已做字节绑定的解析回归;这不等于所有数据库版本上的实际 SQL 执行验收,未支持的方言模板须先补明确语法和回归,不能降级原样执行。
Web 应用可用 RuntimeAssetsOnly=false + IncludeSource=false 同时携带 SharedPublicRuntime 和声明式资源,六张标准应用基础设施表仍按权威闭包导出。 Inspect 和 Publish 使用完全相同的选择、CommittedProof 及运行清单,Publish 再传 ExpectedResourceSnapshotHash;旧稀疏选集必须显式刷新,不能退化为整表。 RuntimeAssetsOnly=true 继续拒绝任何资源选集。
现有 microi_run_engine.params 为通用对象,已能原样透传此选集,仍须 confirmExecution。这不代表线上导出器已升级,也不能以私有源码含 Manifest 代替正式包资源。接口默认禁用须另按实时能力配置并独立回读;当前 microi_generate_system 的引擎 upsert 不会透传 IsEnable/StopHttp。
后台规则审批表 mci_runtime_installation 的结构可由责任包安装,但审批业务行 禁止经导出/导入 DataSets 种入、覆盖或恢复;只有严格零行依赖允许通过。 可信程序集注册与管理员审批是独立动作,不能以商城发布或包安装代替。
标准官方控制面现将 export-package.js 纳入固定单资源白名单,沿用 Resources[{Name,Content,ExpectedRemoteSha256}]、可信官方授权、同事务行锁及回读。 先 CAS 升级控制面,再 CAS 发布导出/导入/发布器,最后从完整母版发行归属商城包; 源码、包正文、不可变快照和公开下载都须独立验证,不能只更新本地镜像。
源码 ZIP 导出与制包校验
应用商城 v8.4.12 的 ai_app_download_source_zip 只导出应用当前活动私有源码,参数为 AppId(兼容 ProjectId)。请求中的租户必须与会话一致;不接受历史 VersionId/VersionNo。 服务端重新读取当前账号的启用状态与权限,只允许真实超级管理员或该应用当前拥有者下载, 访问密钥会话不能读取私有源码。源码和编译 ZIP 仍分别交付、分别验收。
活动根以 sys_microistore.PrivateSourcePath 为准。文件必须属于当前租户和应用、位于该根的 精确子路径、StorageScope=Private、VersionId 为空,且未删除、不是目录。原子同步已完成后, 活动根仍可能位于 ai-app-source-staged;判断依据是已提交的应用指针与当前文件元数据, 不能只因目录名含 staged 就回退旧源。历史版本、未提交的源、上传会话和 upload/v* 运行文件 均不进入源码 ZIP。没有活动基线时停止,不以历史文件代替。
安装器 v3.0.8 在私有桶内为包中源码建立 ai-app-source-staged/{AppId}/store-{SourceManifestHash} 活动目录。每个对象的精确地址为 /{OsClientLower}/{活动目录}/{FilePath},保留路径大小写、中文与空格;旧上传器带日期、 时间戳的地址不能直接写成活动源码。安装器使用既有 CopyObject 保留旧对象,复制前后通过 GetObjectSha256 验证原始字节摘要和大小,再写当前文件元数据。目标已存在但内容不同、 复制能力缺失或存储结果未确认时停止;复制响应丢失只能通过目标实际字节摘要确认。 同版本重装也修正旧路径,源码校验及复制遵守资产分片预算,已提交前缀按同一清单根幂等复用。
安装器 v3.0.9 从 Build/BuildRepair 或后续应用检查点恢复时,也复用已经提交的 规范源码前缀,避免完成源码后再次从头消耗分片预算。应用商城 v8.5.7 包含此修复; v8.5.8 保留该修复,并对齐唯一源码根已验证的共享微服务清单,运行文件字节保持一致。 升级后继续回读原任务和原请求键,不重建安装请求。未知资产类型、非规范根、未验证 条目和元数据差异仍需校验,任务百分比不能代替实际成功及源码 ZIP 的完整验收。
源码 ZIP v1.2.6 在读取对象前及生成后,用全部当前行的原始 FilePath/SHA-256/Size 重算该 store- 根承诺的清单摘要。安装分片中旧根只剩部分行、清单漂移或摘要根格式错误时 直接拒绝,不能把剩余文件导出成完整源码。source/ 包装目录只影响 ZIP 条目名,不改变 安装根的原始路径摘要。
应用商城 v8.5.9 的源码 ZIP v1.2.7 优先复用既有私有文本读取和 Base64 能力, 避免大型 UTF8 源码的 CLR 字节数组在 Jint 中逐字节复制。采用文本路径前核对 UTF8 原始字节摘要和大小;BOM、换行保持原样,二进制内容仍通过原字节路径导出。 读取失败或异常立即停止。最终返回的同一 ZIP 仍逐文件核验路径、大小和原始字节 SHA, 活动清单根及生成前后权限检查保持不变;旧节点缺少文本能力时保留原兼容路径。
升级后仍须实际下载原生源码 ZIP、逐文件验签并在全新目录完成责任测试;安装任务成功不能 代替源码完整验收,也不能通过放宽 ZIP 权限或精确路径校验修复旧路径问题。
历史微服务安装可能已生成正确的版本目录,而 root/latest 固定入口尚未恢复。具备历史安装 恢复能力的后端会从当前租户主库核对已发布应用、唯一同版本历史行、启用的文件服务和全部 公开文件;三方路径、SHA-256 与大小必须一致,且没有安装任务在途或 V3 发布指针。 恢复器复用应用发布租约,先验完整版本对象,再复制和回读固定入口,并在每次复制前后复读 权威元数据。它不重发原安装、不改历史版本身份或私有源码,也不修改业务数据。 对象存储没有跨提供者的条件复制时,旧复制仍可能迟到;后端持续按主库与实际字节检查并 收敛,不能把一次校验写成永久原子切换。缺失、歧义、失租或同版本重装漂移均停止本轮。 验收需分别核对安装原任务、版本对象、固定入口、API 文件和真实页面业务;后端源码测试或 安装任务成功不能代替线上字节、用户操作及业务数据保全证据。
导出前分页读取完整清单,拒绝重复路径(含仅大小写不同)、路径别名和超限文件;通过当前租户 私有 HDFS 字节入口读取每份文件,核对真实长度。已有 CreateZip 原子生成归档后,优先用 可信 ExtractZip(兼容节点的 ReadZip)对同一返回归档核对每个条目的路径、大小和原始字节 SHA-256,以及文件总数与总量;原子存在但返回失败或不完整时必须停止,不能回退放行。 旧节点缺少解压核验原子时,每份原始字节仍须校验摘要;原生 CLR SHA-256 不可用时复用既有 编译 ZIP 的 ES5 原始字节算法。生成 ZIP 前及核验后重读账号、应用指针和文件清单,发现撤权 或漂移即不返回文件。私有字节读取或摘要校验无法完成时失败关闭,不能改用对象摘要代替实际 下载字节。失败只返回不含身份或路径的静态阶段。
成功结果增加 FileCount/TotalSourceSize/SourceManifestHash。清单摘要按路径的序数排序,逐行以 Path\tSha256\tSize 连接,再对 UTF-8 文本计算 SHA-256。导出接口的 Sha256 是原始 ZIP 字节摘要; 资产准备器历史协议中的 ZIP Sha256 是 Base64 文本摘要,两种口径须分别核对。制包超时后先按 真实对象清单回读,逐文件核验源码及编译产物,不能将上传完成、同名 ZIP 存在或解压后能构建 当成发行版正确。重复条目、旧字节或未知结果必须阻止发布,保留失败回执。
下载源码还须能在全新目录安装依赖并执行该应用声明的全部责任回归,再完成类型检查和 生产构建。仅在发布者工作区测试通过,或解压后可以编译,不能证明独立源码完整。 默认测试不得读取发布者临时冻结树、兄弟应用或要求平台仓库存在;需要历史兼容模块时, 随应用测试夹具交付已发布原字节,并记录原版本、路径、大小与完整 SHA-256,保留原业务断言。 工作区统一源码契约由中央 Full 入口验证,独立下载应用不要求取得整套平台源码。
应用商城 v8.4.17 的完整制包器将 .mjs/.cjs/.mts/.cts 与既有脚本文件一起按 UTF-8 文本读取。优先调用既有当前租户私有文本原子,只有 Code=1 才消费返回内容,避免给正常 现代模块逐个发行浏览器临时审计地址再下载。旧节点缺少文本原子或返回读取失败时,继续 保留原私有审计 URL 回退;审计票据异常仍停止,不能绕过权限或审计。图片、字体、ZIP 等 二进制继续保留原始字节;完整模型仍须逐项核对已冻结源码与构建清单的实际大小和 SHA-256。 单次导出超时先核对既有执行链是否结束及失败原因,再安排只读重试,不能同时启动残留导出。
编译 ZIP 的运行类型优先读取 ApplicationType;历史 AppType 只在缺少运行类型时兼容,不能把“官方应用/社区应用”分类当成运行类型。逐项下载仅接受实际 HTTP 200,并使用既有严格 SSRF 传输禁止重定向;合法 JSON(包括 .vite/manifest.json)由冻结清单的真实字节大小和 SHA-256 决定身份,不能仅因内容含 Code 字段将它误判为业务响应。每个新 ZIP 的 microi-app-version.json.RuntimeManifestHash 必须非空,并等于完整已核验文件清单的 Path\tSha256\tSize 摘要;当前 V3 版本还须等于权威 Completed 提交版本及微服务清单,下载前后版本指针、请求指纹或行版本漂移即拒绝。缺失版本哈希的旧 ZIP 不进入新正式包。
仅共享编译运行产物
只希望安装者获得运行应用、无需在目标租户创建业务资源时,可在 ai_app_publish_store 中显式启用 RuntimeAssetsOnly=true。 它复用已提交的公有编译运行产物,不随商城包交付源码,也不导出发布方的表、 接口引擎或业务数据。仅设置 IncludeSource=false 不会自动启用此模式。
| 条件 | 要求 |
|---|---|
| 发布协议与类型 | 显式 ProtocolVersion=3、ApplicationType=Web、IncludeSource=false。 |
| 运行产物 | SharedPublicRuntime 必须通过已提交版本的 CommittedProof 和运行清单校验。 |
| 资源选择 | 请求中的菜单、表、接口、工作流、任务、数据、路由、页面和资源策略均为空。既有商城行的 SelectMenu/SelectTable/SelectApiEngine/SelectData 也必须为空;非空时拒绝发布,不会自动清除。 |
| 包资产 | PreparedAssets.MenuContract 为空;不能同时使用 DatabaseOnlyBuild。 |
下面是应合并到完整发布参数中的模式字段,不能替代应用身份、版本、资产和提交证明:
{
"ProtocolVersion": 3,
"ApplicationType": "Web",
"RuntimeAssetsOnly": true,
"IncludeSource": false
}现有 MCP microi_run_engine 的 params 可直接传递这些字段。先对同一组冻结参数 调用 Action=InspectResourceSnapshot,取得 ResourceSnapshotHash;再以 Action=Publish 和对应 ExpectedResourceSnapshotHash 发布。 两次调用都保留 RuntimeAssetsOnly=true,不能在检查后更换版本、资产、提交证明或资源选择。 发布端须先更新到支持此开关的 ai_app_publish_store;不支持时不能回退成普通包发布。 省略此开关或设为 false 时,仍使用原有打包流程。
发布后须下载实际商城包核验:DDLStatements、PhysicalColumns、DiyTables、 DiyFields、DataSets、SysMenus、WfFlowDesigns、WfNodes、WfLines、 SysApiEngines、ScheduleJobs 全部为空;SourceFiles 和 BuildAssets 为空, SourceZip、BuildZip 为空,运行交付只有 SharedPublicRuntime。 该模式不会迁移服务端业务;安装后的身份、接口与数据仍须按应用自身的服务契约验收。
安装、升级与安全
随包数据中的固定自动编号会保留:导入器
v2.9.8按目标表的AutoNumber字段元数据, 在新增后恢复包内明确给出的非空编号,并在安装事务内回读校验,避免打印模板等资源被改成流水号。UpsertById升级或同版重装也会恢复声明的编号;InsertIfMissing已有记录仍保留租户值。 未给出或为空的编号继续自动生成。旧租户先更新应用商城,再重装受影响应用;编号冲突或回读失败会停止安装。SharedPublicRuntime复用已经提交的公有编译文件,不上传客户端源码,也不复制大体积素材。 包内EntryUrl保持不可变且不带查询参数;安装器生成的PreviewUrl另带目标租户的apiBase和OsClient,不得直接继承发布方默认租户。目标系统设置的ApiBase必须有效, 启动地址不包含 Token。导入器需达到v2.9.0;旧租户先更新应用商城,再重新安装共享运行应用。 验收须从安装后入口登录,并检查实际 HTTP 和 SignalR 使用目标租户,不能只检查安装任务成功。微服务安装兼容没有
ApiBase配置字段的新租户和历史还原库:打开时优先使用同一租户宿主传入的 API 地址,独立打开时使用绑定目标租户的 API 稳定入口,兼容反向代理路径。不会继承发布方租户或把文件 CDN 地址当成 API。独立 Web/UniApp 的公有 HTML 仍需在目标租户系统设置中配置实际
ApiBase;配置缺失时安装器会说明原因和修复位置。个人中心兼容登录接口返回的角色数组、JSON 字符串与空值。应用商城定义、私有源码、安装、升级和卸载属于控制面,只允许
Level >= 9999。官方平台身份不能只看租户名。只有
OsClient=iTdos且当前服务节点持有与平台内嵌官方公钥匹配的 License 私钥时,V8.SysConfig.IsOfficialPlatform才为true。官方环境会隐藏【安装】【更新】【重新安装】【安装离线包】【全部安装/更新】,服务端也会拒绝对应安装接口;普通部署即使把租户命名为iTdos也不会被误判。离线包必须校验 Manifest、平台最低版本、依赖、文件哈希和资源清单;包内不能携带源租户
OsClient、数据库、Redis、对象存储、MQ/MQTT、AI 或第三方密钥。安装使用后台任务和稳定
OperationId,阶段进度/checkpoint 写共享存储。安装成功后先写商城安装事件,再与InstallCount + 1同事务提交;同一操作的重试只回读已有事件。两个节点重复领取时,由幂等键与数据库唯一/条件更新保证副作用一次。非官方环境的页面按钮【全部安装/更新】固定只规划
ApplicationType=Platform的官方平台应用,并只处理Uninstalled和Outdated两类状态;UniApp、Web、MicroService 及其它社区/AI 应用仍由用户逐个选择,已是最新版的Installed不会重新安装。计划、当前应用和子安装 checkpoint 保存在共享数据库的后台任务CheckpointJson,不要求租户额外创建批量计划表;右上角后台任务中心显示总量、当前项和整体进度,节点重启或租约转移后继续执行。MySQL 历史宽表接近 65,535 字节行内上限时,导入器只对明确触发行宽错误且不参与索引的
varchar配置列改用mediumtext行外存储,并把类型覆盖写入后台任务 checkpoint,节点切换后继续沿用;索引字段或其它 DDL 错误不会被自动吞掉。应用包中的长连接串、密钥、回调地址、域名清单等配置字段应直接声明为mediumtext,避免依赖运行时回退。历史表已经耗尽行宽时,新增
TEXT也需要行内指针,单独改新增列仍可能失败。导入器从v3.0.7起先尝试将本次长度不少于 255 的长varchar改为行外文本;短日期列保留原类型。仍不足时,只在本包声明拥有的表内,对包中明确声明的既有可空、无默认值、无生成属性且不参与目标真实索引的长varchar无损扩宽,保留内容、字符集、排序规则和注释,每条 DDL 后强回读,最多八次调整。引用表、客户自有字段、索引列及其它 DDL 错误继续明确报错。遇到此类历史宽表错误,先更新应用商城再执行【全部平台应用安装 / 更新】。类型调整写入分片检查点,后续安装保留目标已扩宽的文本容量;DDL 不随事务回滚,失败后必须先回读真实结构再重试,不能手工删除历史列或清空业务数据。验收需要完整批次成功,并立即执行一次零安装/零更新重跑。
MySQL 列只有默认值变化时,普通常量使用
ALTER COLUMN。时间列的CURRENT_TIMESTAMP使用兼容 MySQL 5.7 的MODIFY COLUMN,从目标列元数据保留类型、精度、可空性、ON UPDATE与注释,并固定ALGORITHM=INPLACE, LOCK=NONE;数据库不支持时明确失败,不退回整表复制。写后重新读取默认值,等价的大小写、空括号和零精度写法不会造成重复改列;字符列中的同名文本仍作为普通字符串。批量任务以单个应用作为外层事务和恢复边界。规模可控的小型官方包一次完成,避免每 8 个字段反复下载同一包并重新排队;超过字段、表、DDL、流程、随包数据或资产安全阈值的大包仍使用内部安全分片,因此不会为了提速牺牲大包的内存保护和断点恢复。
批量引擎只接受平台持久化任务 Worker 注入的可信调用标记,并同时核对任务 Id、任务信封与正数 fencing token。HTTP 控制器会主动剥离该标记,因此即使为兼容旧服务节点将引擎配置为
StopHttp=0,浏览器或外部请求也只能得到“必须通过持久化后台任务执行”,不能绕过后台任务直接安装。商城页面按钮及其调用的接口引擎、权限和数据结构必须由同一版本应用包交付。导入器会在接口引擎新增/更新后清除缓存并回读 Key、启用状态、HTTP 状态和完整源码;任一项失败时整次安装回滚,不会留下“按钮可见但接口不存在”的半安装状态。
发布器必须把请求发布的版本精确传给资产准备器,并回读
RequestedVersion == PackageVersion == PackageInfo.Version;禁止资产准备器静默改用“最新版本”。菜单、表和接口引擎的发布选择必须从本次包正文持久化,不能沿用上一版选择状态。接口引擎资源必须在包内声明
ResourcePolicies.ApiEngines。用户在商城选择安装、更新、重装或历史版本时,所选且已校验的包正文决定Managed资源,版本或本地差异不能制造整包冲突;CreateIfMissing只在 Key 完全不存在时创建。启动恢复仅允许app.microi.bootstrap.json通过绑定当前租户和固定导入器的一次性宿主可信上下文执行,V8 参数不能伪造授权。启动恢复保留满足必要路由契约的更高版本接口及完整商城运行资产,避免覆盖用户已手动完成的更新。导入器 v3.0.10 同样更新包内明确声明为
Managed的get-microi-upgrade-resource,不得无条件跳过并仅推进安装版本。没有该声明的历史包保留原保护边界;安装控制接口源码不会授予官方发布权限,Publish / PublishBatch / ReconcilePublishedApiEngines仍必须通过固定官方租户与可信后端鉴权。安装成功后逐项核对完整源码和版本。CreateIfMissing表示租户拥有的扩展 Hook:首次安装创建,后续更新永远跳过;同一 Key 一旦交给租户,后续版本也禁止改回Managed,确需新官方核心时必须发布新 Key。官方应用必须采用“受管核心接口 + 租户扩展 Hook”,客户定制只写 Hook,扩展 Hook 按稳定EventId幂等。可信官方核心会在升级时被覆盖,因此不能把租户业务修改直接写进核心。商城源业务固定由
platform-marketplace-source(Managed)编排,个性化逻辑只写platform-marketplace-source-hook(CreateIfMissing,默认正文精确为return { Code : 1 };)。登录在任何远端配置读取、密码发送和凭据保存之前调用BeforeMarketplaceSourceLogin;断开在删除服务端凭据之前调用BeforeMarketplaceSourceDisconnect。Hook 失败会直接阻断操作,不能静默跳过。商城源 Before Hook 的安全载荷只包含
Stage / SourceApiEngineKey / Action / SourceId。ApiBase、远端OsClient、账号、密码、Token、签名地址和凭据密文不得进入租户 Hook。登录协议、HTTPS/重定向限制、密码加密、Token 保护与密钥隔离继续保留在可信 C# 网关中;成功或失败后的脱敏审计再由 Managed V8 执行。其它已有资源使用存在性检查与差异合并;客户自定义 V8、全局配置和非包拥有字段不得被整表覆盖。
更新遵守“先扩展、后迁移、再收缩”,新旧节点滚动期间 API、数据库和缓存合约兼容。
定时任务是应用包的一等资源。导入器完成表、字段、数据与其它
PostSchema资源后,必须在独立ScheduleJobscheckpoint 中幂等创建/更新 Quartz 任务并回读运行元数据;任务阶段失败时不能提前写入已安装版本。安装成功后回读表、字段、接口引擎、菜单、权限、页面、工作流、定时任务和版本,并执行真实 HTTP/UI 冒烟。官方发布源只负责制作和发布应用,禁止在自身执行安装、更新、重新安装、批量安装及
ValidateOnly;安装链路必须在非官方目标租户或本地非发布源环境验证,不能削弱发布源隔离规则。
商城入口恢复与可选应用更新
首次启动不需要先安装全部平台应用。 默认恢复面以应用商城、表单引擎、模块引擎和 系统设置的核心依赖为界,包含普通账号登录与权限所需资源。它由一个最小恢复包交付, 并不表示其来源的完整 SaaS、账号管理等应用已经安装。
| 场景 | 安装范围 | 验收终点 |
|---|---|---|
| 默认启动/历史库恢复 | 登录、权限、导航、商城安装所需的核心结构和接口 | 能登录并打开商城 |
| 用户按需安装 | 用户选中的应用及其明确依赖 | 后台任务成功,实际功能可用 |
| 全部平台应用维护 | 用户显式发起的完整平台应用集合 | 全部任务终态及资源核验 |
三种场景分别计时。全部平台包安装的耗时不是启动耗时,更不能通过延长等待时间把 几十分钟初始化作为默认体验。最小空库验收应先完成登录与商城访问,再实际安装一个 可选应用;不能先装完全部应用再声称最小启动通过。
制作新空数据库时,同样只继承应用商城、表单引擎、模块引擎、系统设置、系统账号和启动投影的既有安装身份;不能仅凭“平台应用”分类或 app.microi.* 前缀保留所有应用。空库清理 SQL 只用于独立模板副本,不会卸载已经运行的客户租户应用。
Microi.Server/Microi.Upgrade/ 只维护系统启动、普通账号登录、菜单导航及应用商城安装/更新所必需的恢复面。它不自动安装或升级 SSO、AI、通知、备份、OCR、翻译、工作流等可选应用。用户在商城选择相应应用后,才执行该应用包的安装或更新。
完整官方应用的源码、生成器、测试、同步器及发行包统一放在 Microi.Server/OfficialApplications/Resource/。build-bootstrap-package.mjs 从官方包按显式表和接口清单生成恢复包;升级程序集只嵌入生成的 app.microi.bootstrap.json 和 import-package.js,不随完整平台包增加接口自动扩大启动闭包。共享核心实体所需的物理兼容列与商城安装元数据保留,包不携带业务数据种子或定时任务。商城菜单只补齐必要祖先,平台微服务只注册 /marketplace 恢复页面。
启动投影不携带完整 SaaS 管理界面的字段配置。运行时仍保留所需物理列,并按可信 配置读取连接、签名和存储信息;需要编辑完整 SaaS 功能时,再安装 SaaS 引擎应用。 基本控件只移除其它控件的配置,保留当前控件、共享属性和未知扩展。此缩减不删除 已安装应用的字段、配置或数据。
启动前在共享租约下修复必要物理字段和普通登录元数据、接口。首次启动缺少商城入口时,必须在接受登录前通过同一条最小恢复流程安装持久队列和商城包,并验证菜单、服务、页面绑定及数据库内联资产;不能先允许登录到空菜单或404页面,再等待后台补齐。完整恢复成功后才前向保存 ServerVersion,失败保留旧版本并允许幂等重试。已覆盖基线的租户跳过历史迁移,仅检查必要物理协议与商城就绪状态。更高版本且契约完整的手动更新保持原样;既有租户 Hook(包括禁用和软删除)不覆盖。
容器 stdout 使用 【自动升级状态】 记录租户、阶段和失败原因。进程已启动、数据库版本已更新或页面能打开都不能单独证明任意应用安装成功;商城安装还要等待持久后台任务成功终态并回读实际资源。官方渠道发布和客户租户安装/服务器部署分别验收。
官方应用源升级“发布控制面自身”的校验规则时采用两阶段自举:先只发布并回读 get-microi-upgrade-resource 的完整源码与 SHA-256,确认动态路由已加载新版控制面;再原子发布应用包,最后用独立 RPC 投影全部 live 接口。第二阶段遇到 524/超时只能通过应用包哈希、接口元数据和 Managed 完整源码摘要判断事务是否已经提交;缺失接口、摘要缺失和网络超时必须分别报告,并以有界低并发重试恢复,禁止盲目重复覆盖或把“包已上传”当成 live 接口已经就绪。
应用商城 v8.4.16 的 ReconcilePublishedApiEngines 保留默认九套平台应用的全量投影规则。发布独立系统日志包时,显式传 ProjectionScope: 'SystemLog',并且 Resources 只能包含 app.microi.sys-log.json 及其实际已发布完整包的 ExpectedSha256;包内 PackageInfo.AppId 必须为 app.microi.sys-log。这个入口继续执行官方管理员鉴权、完整包校验、事务行锁、Managed/CreateIfMissing 所有权及写后回读。它不会接受其它文件、任意作用范围或部分九包投影,也不代替目标租户的商城安装。
源码发布前可在工作区运行 node Microi.Server/OfficialApplications/Resource/refresh-resources.mjs --validate-only,提前检查全部本地资源契约。此模式不联网、不写资源或同步基线,也不允许与发布参数组合;它不能代替完整测试和线上发布回读。控制面校验采用最低语义版本加严格安全能力检查,不会因为已升级到更新版本而误拒绝;通知等可选功能一旦在包中声明,必须携带完整接口及资源策略,半套功能和未知接口仍会阻断发布。
这里的数据库内联不是把所有微服务长期塞进数据库,而是平台启动面专用的受信任例外。microi-platform-service 的已校验编译产物同时内置在 SaaS 引擎包和应用商城包中,固定声明 Source=NotIncluded、Build=DatabaseOnly、StorageMode=db,最多 256 个文件、5MB。新环境即使尚未安装 MinIO、OSS 或 S3,仍应能打开应用商城;个人中心和完整系统设置页面以对应应用已经安装为前提。前端通过通用微服务宿主先调用 Resolve,旧后端才回退稳定 /micro-app/.../index.html 入口,不携带第二份平台业务源码。
HDFS 故障时按能力降级,不能把“应用商城页面可打开”和“任意应用都可安装”混为一件事:
| 能力 | HDFS 未安装或不可用时 |
|---|---|
| 平台内置微服务、应用商城页面 | 使用程序集内置包导入的数据库运行产物,继续可用 |
| 通知中心的平台应用恢复入口 | 继续可用,不依赖商城微服务页面挂载成功 |
同样满足 DatabaseOnly 严格边界的受信任小型平台包 | 可安装,但仍要校验包、哈希、事务和回读 |
| 普通 MicroService / Web / UniApp 安装、源码在线编辑、上传与文件预览 | 明确显示对象存储不可用并停止相关动作;不得写入半套数据库记录 |
官方发布源维护 microi-platform-service 时,正式源码根由 platform-service-release.json 唯一指定。发布前运行 embed-platform-service-bundle.mjs --verify-only,确认源码版本、源码清单哈希、dist 哈希、路由、SaaS 引擎包和应用商城包完全一致;官网资源发布器还会要求源码根来自无未提交修改的 Git 提交。HDFS/CDN 若作为镜像,必须回读到同一 RuntimeManifestHash 后才可切换。租户同步目录和前端主包都不是该应用的第二事实源。
右上角【通知中心 → 平台应用】为超级管理员提供【安装/更新全部平台应用】。该入口直接提交 bulk-import-microi-store-packages 持久化后台任务,不依赖应用商城微服务页面能否打开;任务固定只处理 ApplicationType=Platform 且状态为 Uninstalled / Outdated 的应用,已是最新版和其它应用类型均跳过。官方应用源节点不会显示该按钮。
遇到 MICRO_APP_NOT_AVAILABLE 或“微服务不存在或已停用”时:
- 同时更新后端和 PC 前端源码,重启 API,确认日志中的“基础应用升级”已完成且没有导入失败。
- 刷新 PC 页面并核查最小启动包恢复失败的具体原因,修复后重启重试;不能用安装全部平台应用来掩盖商城启动依赖缺失。商城可用后,用户再按需安装单个应用;显式全量维护仅用于用户确实选择全部平台应用的场景。
- 任务成功后重新进入应用商城,分别核对页面可加载、平台应用版本和安装记录。源码构建成功、升级日志成功、后台任务成功和真实页面可访问是四个独立验收事实,不能互相替代。
AI 平台治理中心
官方应用 ai-platform-studio 通过同一个安装包交付门户、身份与权限、配置、功能开关、发布审批与执行、服务治理、Trace/日志生命周期、可观测告警、组件资产、页面源码桥接、协作和可恢复导入。包内固定包含 40 张治理表和 5 张运行基础表(合计 45 张表、873 个字段)、42 条稳定菜单兼容记录、64 个接口引擎、1 个治理任务、10 条微服务路由和已校验的构建资产;导航仅显示一个 AI平台治理 MicroService 入口,历史工作台和 40 个数据菜单隐藏,能力均在工作台页面中进入。
其中 57 个官方核心接口使用 Managed,7 个租户扩展 Hook 使用 CreateIfMissing。首次安装和后续升级都必须核对两类策略数量;安装后打开 /micro-app/ai-platform-studio/overview 做真实页面冒烟,并逐项验证配置、发布、服务、可观测、资产与协作入口。完整能力与验收见 AI 平台治理中心。
复杂安装交互使用 V8.OpenAppDialog;后台安装调用 V8.ApiEngine.RunBackground。不要在 ConfirmTips 中拼接上传控件和大段内联 HTML/事件。
完整规范见源码 microi.skills/app-store/SKILL.md 与平台安全与兼容基线。
旧开关列的二进制文本兼容
导入器 v2.9.1(应用商城 v8.3.6)补充识别旧 BIT 被历史工具转成文本列后遗留的单字节 00/01。仅当应用包的表/字段元数据明确将该列声明为 Switch 时,程序才规范为数值 0/1 并继续物理列复核。真正的 BIT 列仍按数值类型处理,不扫描或改写为文本;普通字段、多字节二进制与其它非法字符串仍失败关闭。
遇到“元数据 int、物理 varchar”的升级失败,应从正式结构导出检查 PhysicalColumns 与失败样本编码,再通过更新后的导入器重试同一已校验包。不要手工清空业务行、强制把所有非法值转零或关闭物理列检查。
工作流升级与租户审批配置
应用商城 v8.3.32(导入器 v2.9.9)支持包声明 Installation.ConfigurationPolicy = "PreserveTenantValues"。先升级应用商城, 再安装声明该策略的业务包;未声明的历史包继续使用原有覆盖规则。
| 升级情形 | 处理结果 |
|---|---|
| 业务表、节点用途和连线结构兼容 | 保留目标启用状态及节点的用户、角色、部门绑定;受管流程代码继续更新 |
| 新增节点、改变节点用途、业务表或连线路线 | 停用流程,保留仍兼容节点的绑定,提示重新配置并验收 |
| 结构变化且存在未处理待办 | 拒绝改图,须完成或撤回在途审批后再更新 |
| 写入失败或实际字段回读不一致 | 当前安装事务失败,保留可诊断错误 |
首次安装仍使用包中的停用模板,由目标管理员绑定真实审批岗位后启用。 结构变化后应复核完整图形,包括历史多余节点和连线;安装器不代替管理员删除审批历史。 验收必须覆盖已配置租户的升级和同版重装,不能只检查空模板安装成功。
空绑定、停用的工作流模板也必须逐字段对照真实数据库结构。预制包发布前,应将流程、 节点和连线的每个属性与目标支持的物理列及类型核对;新增列须由同包声明交付,未知属性 直接拒绝。给未知字段赋值 0、空字符串或 [],不能证明它能落库,也不能通过默认值 补齐来绕过写入后回读。保留原生已有字段与审批配置,不得凭相似名称发明控制项。
导出器的原生导出和 PreparedPersistPackageByteBase64 发布入口,会重新读取当前租户 数据库中 wf_flowdesign/wf_node/wf_line 的物理列,检查资源属性及大小写重复名称。 包内自报的 PhysicalColumns 不能授权新字段;数据库已存在的租户定制列继续合法, 新增列应先通过正规结构交付并回读。MySQL/MariaDB、SQL Server 和 Oracle 使用各自 当前数据库目录。目录读取失败、为空或数据库类型缺失/不支持时停止制包;无工作流的老包 不要求工作流目录。失败发生在 HDFS 上传、日志写入、发布 CAS 和商品指针更新前, 安装器仍独立严格回读字段,不能用发布前检查替代目标安装验收。
普通表单布局也须区分保存字段与界面控件。无 Type 的 TableChild 通过真实子表和外键 展示关联记录,不能凭控件名称生成 varchar 列。以当前物理目录核对 DDL 与 PhysicalColumns;已有真实定制列和子表配置、数据保持原样。重复生成官方包还应完整保留 已声明的接口、正文、鉴权和资源策略,接口数量变更须由实际母版与正式包证明,不能静默裁剪。
发布方还须核对安装包中的实际节点正文。安装模板应从当前母版定义生成, 历史映射仅提供稳定资源 Id;构建时逐节点校验 V8 正文和条件代码。 源码同步成功或管理员提交成功,不能证明普通岗位安装后可用。 例如职责配置升级为 RoleMapRef 后,旧模板若仍按内联角色配置读取, 可能拒绝普通销售。应更新正式包、保留目标审批绑定,再用原合同和原请求键验收。
应用商城 v8.3.33(导入器 v3.0.0)修复了流程写入与回读使用不同事务的问题。 新流程、节点和连线现在与配置读取共用同一事务,写入后立即可见;任一流程资源失败时一起回滚。 旧安装器在可重复读隔离下可能报告“工作流写入后回读不存在”,并在重试中留下部分流程。 遇到该错误应先升级应用商城,再以原来已校验的业务包恢复安装;保留失败任务记录, 不要删除业务资料、流程历史或通过反复改包绕过回读检查。
进销存价目与报价的完整升级
进销存价目/报价升级需将业务接口、增量字段、受控原生事件、六套原生流程及 /pricing、/quotes 微服务页面作为同一包闭包交付。只更新 mci-inv-business 会因目标仍缺字段而失败;原生资料表也不能开放直接CRUD来代替金额计算、审批和报价来源锁。
价格选择及税率由服务端按当前租户资料重算。低于最低价或额外折扣的报价/订单即使金额低于一般审批阈值,也需要两位不同的实际审批岗位人员。报价获批后转为一张草稿订单;同请求重放或并发转换读取原来源订单,库存和资金继续走原有业务审批/过账。新增报价模板首次安装保持停用,目标必须绑定本租户真实人员再启用。升级与同版重装声明 PreserveTenantValues,保留既有角色配置、审批绑定、业务数据与 CreateIfMissing 租户Hook。
价目/报价的本地源码、规则回归、生产构建、官方包发布、隔离租户安装及真实岗位/浏览器验收分别记录。候选通过回归不能作为整套进销存60项需求的商业完成证明;调拨、盘点、期初、成本调整等仍按各自需求验收。
权威单位升级还需先安装公共目录的单位引用协议,再按完整包加入消费者的可空快照列。服务器保存SKU、交易单位、基本单位、精度、固定系数、版本与目录摘要;数量阶梯按基本数量选价,交易单价精确换算。首次报价转单核对当前目录版本;已批准履约与原单退货沿用历史快照,不以当前改名或换算覆盖旧账。未知或多义条码明确失败,重复扫描按同SKU及单位精确累加;客户端传入的名称、Factor和摘要均不作为事实。成功请求回执也重算仓库及目录权限,授权撤销后拒绝继续读取。
存量余额缺少真实原流水/明细的单位证据时停止合并,不能根据当前目录回填猜测历史;单位或精度不一致须先做受控迁移核对。新执行单的批准摘要不能通过清空版本标记降级。这里说明升级和操作合同;只有新完整包、隔离安装、实际岗位/原生流程、金额库存守恒及浏览器回归均完成后才记录该版本验收通过。
成本调整通过资金工作台保存申请、提交独立原生审批、复核结果和确认过账,只调成本金额。升级需同时安装 17 个可空扩展列、受管正文、停用的成本流程模板和完整微服务运行产物;不能开放原生 CRUD 直接修改成本池、审批状态或快照。目标在独立 CostWorkflowMap 配置真实流程、节点及两位不同的实际用户,绑定本租户成本职责与仓库管理授权后再启用;旧 WorkflowMap、原启用流程的人员与拓扑保持。
批准和过账时重新检查当前权限、开放期间及原成本池版本。正数量历史池币种为空时拒绝调整,不能默认人民币或从最后一条流水猜测整个成本池币种;必须先通过完整历史来源链设计受控纠错。可信原生退回/取消可恢复申请,期间正常收发导致成本池变化不会阻止此无金额副作用的终止复核。过账追加 Qty=0 的成本调整流水,记录币种、成本前后和来源审批;库存数量、预占、冻结和资金余额不变。响应未知保留原请求键,成功重放仍重新核权。工作台显示正规 SKU 名称另须公共目录独立读取授权,不能借成本职责自动取得目录管理权限。
成本版本的责任回归、真实原生普通岗位审批、台账守恒、桌面与窄屏、并发及两节点恢复分别验收;新增字段和流程模板安装成功不代表这几个验收都已完成。
应用包中的物理索引
应用商城 v8.3.34 补齐标准导出与 AI 应用组合包的物理索引:唯一索引和普通复合索引 随责任表进入独立 DDL,安装时在建表和补列之后建立;同名索引定义冲突会停止打包。 旧包不会自动获得索引,发布者须更新商城后重新导出业务应用,再发布新的应用版本。
| 验证位置 | 必须核对 |
|---|---|
| 官方母版 | 真实索引名称、唯一性及列顺序 |
| HDFS 包 | 同一表的建表语句和每条索引 DDL 均存在 |
| 安装后 | 物理索引与包一致;业务重复键被拒绝,重装无重复索引 |
当前标准物理结构导出支持 MySQL/MariaDB 的完整列升序 BTREE、单列 Id 主键。 前缀索引、表达式、全文、降序及其它源数据库需使用已审计的专用包;不支持的定义会明确报错, 不能忽略错误继续发布。这里说明的是源数据库的导出边界,目标数据库安装能力须另行验收。
非 Id 主键与检查点恢复
安装器 v2.9.6 从包与目标数据库读取真实主键、自增/identity 信息,保留任意名称及复合主键的非空约束。普通业务字段仍允许 NULL,表单必填规则独立生效。旧包缺少主键信息时也不会把目标主键改为可空或取消自增。
升级失败提示主键不能为 NULL 时,先更新应用商城安装器,再恢复原后台任务的检查点;不要删除主键、清空业务数据或生成不同内容的包来绕过校验。
跨租户安装微服务时,文件、HDFS、OSS 等受托管运行时入口使用目标租户及安装后的 AppKey,不保留来源租户地址;数据库运行时仍使用 db,显式外部运行时保留外部地址。
进销存调拨、差异和历史在途资产
调拨升级须一起交付原生独立调拨/差异工作流、Managed业务接口、只读明细/归宿账、可空增量字段和仓库/财务工作台,不能用开放CRUD补齐业务。在途发出只减源仓;收妥、独立退回及损耗各有不可变移动。部分接收按冻结原成本整分分摊,最后一批消费全部剩余金额,不从目标现池重算或隐式换汇。差异必须另行批准、两仓不同人员确认,过账和成功重放均重新核当前职责与仓库范围;审批模板初装停用且不含虚构人员,原有已启用绑定和租户Hook保留。
历史期末核对按原移动账及业务日期计算,不能把今日余额当作月末余额。汇总数量/金额先在数据库转为十进制文本,跨单位/币种保持逐行;原发出证据缺失、非法归宿、负在途或零数量遗留金额须失败关闭。关账保存可核验在途摘要,超出有界读取容量不能省略历史行;新字段可空且无默认,不自动回填旧余额。源码回归、生产产物、官方包、隔离安装、实际岗位/原生审批、浏览器和两节点故障分别验收,不能把候选测试通过标为60项商业完整交付。
进销存盘点升级与验收边界
盘点升级需要同时交付仓库/财务工作台、受管业务接口、独立审批模板、 不可变观察账和盘差凭证。低代码表单只读属性与隐藏菜单不能代替后端保护; 原生 CRUD 也必须拒绝伪造批准、实盘和库存调整。 当前盘点仍为未发行候选,以下为升级与验收要求,不能据此认定线上已可商用。
- 管理员配置实际盘点职责、仓库范围、独立财务审核人与过账人。 安装模板保持停用且人员为空,不覆盖旧审批绑定、租户配置或 Hook。
- 仓管显式选择同仓 1 至 100 个库存桶。开始时冻结数量、基本单位、 跟踪模式和完整移动账;盲盘不向普通仓管显示账面、成本或他人观察数。
- 本人初盘,另一位当前有权人员复盘。盘中合法收发计入差异, 例如开始 10、随后入库 2、实盘 11,只确认盘亏 1,不能覆盖原 12 件账。
- 财务核对估值,经独立原生审批后由另一财务过账。 盘差数量、成本、序列轨迹、凭证和原请求回执共享事务,资金、预占与冻结保持。
盘盈必须重新检查当前仓位启用且属于本仓、批次启用且属于该 SKU, 过期日按服务器日期判断。盘亏可以清理身份正确的历史停用桶; 序列号净差为零但包含盘盈腿时,仍不能绕过盘盈校验或复活已盘亏序列。 空池盘盈要求实际财务提供精确估值,未知成本币种不能默认人民币。
批准后正常收发改变冻结数量或成本,旧批准不能直接过账。 当前原负责人仍有本仓盘点权时,可核验原流程终态、节点、待办与历史后重开; 旧批准和原回执保留,新实盘必须形成新冻结和新审批。 成功原请求重放仍复核当前授权,响应未知时先回读原请求,不换键重复记账。
升级验收须全分页保存旧业务值、角色、仓库授权、配置和流程绑定。 长正文、V8、冻结快照及回执须核数据库字符数、字节数和完整 SHA, 分段重构后再次反核;截断预览不能证明保留成功。 独立源码下载的完整责任回归、真实普通岗位审批/重开/过账、浏览器及两节点故障 分别验收,候选或单节点模拟通过不代表全部商业需求完成。