我用的nocobase是2.1.19版本,安装插件有一个依赖兼容性提醒:
无法启用,提示错误:Failed to enable plugin: Cannot define property BluebirdErrorTypes, object is not extensible
我用的nocobase是2.1.19版本,安装插件有一个依赖兼容性提醒:
无法启用,提示错误:Failed to enable plugin: Cannot define property BluebirdErrorTypes, object is not extensible
sjgl02 v1.0.139
这个插件导入时支持单表或者多表的自定义数据校验吗?比如导入的数据不符合某种规则;判重等
等修复ai修改出现幻觉了
v2.0.10正式版本已经发布
plugin-async-task-manager 的 CommandTaskType 机制,行数 ≥ 5 万的导入(提交时记录 plannedRows)与「全部数据表」导出任务改由 WORKER_MODE='-' 瞬态 NocoBase 子应用线程执行,大任务的 CPU 密集工作彻底移出主进程事件循环;小任务维持进程内执行(方案 A 让出已覆盖)。
server/commands/run-task.ts(sjgl02:run-task --taskId,.preload() 触发完整应用加载;手动加载 DB 动态集合;命令结束显式 process.exit 防止线程残留卡死队列);WorkerTaskRunner(spawn/取消先 IPC 优雅回滚 30s 超时强杀/异常退出兜底标记失败);task-queue 增加混合调度(shouldRunInWorker)与 executeAsWorker worker 入口;@nocobase/plugin-file-manager 的 server/commands/repair-filenames 缺 default export,导致 runAsCLI(worker 链路依赖)报 callback is not a function,已在该插件源码补 default export 并重新构建(属官方代码,升级官方版本时注意回归)。setImmediate),任务执行期间 API 请求可正常穿插处理,不再出现长时间页面无响应:导入行循环每 200 行、附件处理每 50 条、导出行循环每 200 行、关联表写入每 500 行、附件收集每 100 条各让出一次,吞吐损耗可忽略。已知局限:.xls/.csv 为整文件一次性同步解析(库限制),解析阶段仍可能短暂卡顿,解析后的处理阶段已覆盖让出。src/client/models 注册 Sjgl02BlockModel——/admin 路径下 v2 页面的 sjgl02 区块正常显示、创建区块菜单可添加;src/client/plugin.tsx 增加 pluginSettingsManager.add('sjgl02')——/admin/settings/sjgl02 可直接访问(v1 设置中心外壳),与 /v/admin/settings/sjgl02 双入口并存。Record<tabKey, fn>),仅在「离开脏向导 Tab」或「切回脏向导 Tab(旧实例将被重置)」时弹确认,任务管理/权限管理之间切换不再误弹;向导卸载时注销对应检查,同时修复闭包随 step 变化累积与 ExportWizard 闭包捕获过期 step 的问题。homepage/repository(https://github.com/fengwenkai168/nocobase-plugin),README 增加主页链接。?token= 鉴权,服务端本已流式输出),大体积导出包(如全部数据表 tar.gz)点击后立即开始流式下载并显示系统下载进度,不再长时间无反馈或内存溢出。涉及:任务列表「下载」、任务抽屉「下载导出文件 / 下载导入源文件 / 导出错误报告」。(注:token 入 URL 为需求方确认的取舍,服务请求日志会记录 query。)sjgl02_permissions/sjgl02_tasks 等 6 张),其索引名(如 sjgl02_permissions_created_by_id)与 2.0.x 驼峰表 sync 自动生成的索引同名(PostgreSQL 索引名 schema 内全局唯一),导致升级时报 relation "..." already exists。
idx_sjgl02perms_*/idx_sjgl02plogs_*/idx_sjgl02tasks_*):利用框架 addIndex 按字段去重机制,抑制默认蛇形名索引生成,sync 不再与旧表索引冲突;20260725120000-drop-legacy-1x-tables(on='afterSync'):sync 完成后强制删除 6 张 1.0.x 旧表(不迁移数据),并清理 2.0.x 老库中被替换的旧命名索引;yarn nocobase upgrade 通过、旧表全删、新表与索引正确;二次执行幂等。yarn build 声明构建(dts)的 6 类 TypeScript 错误——task-queue.ts 插件类型引用路径(./plugin→../plugin)、api.ts 请求助手改泛型并补全调用点类型实参、TaskRecord 补 permissionConfigId/permissionType 字段、TaskDrawer 映射表列 render 参数显式类型与统计数值 Number 化、export-engine.ts 字段配置显式 ExportFieldConfig[]、import-engine.ts filterByTk 选项类型断言。修复后插件带声明构建通过、全仓生产构建(yarn build)通过,yarn start 生产模式启动验证正常(无需 pino/real-require 等额外配置,二者为核心包依赖由宿主提供)。m2mStrategy 参数。docs/sjgl02-prototype.html 同步上述交互;修复原型预存 bug(updateEmptyUniqueAlert 局部变量遮蔽全局函数)。编码(code));<a href> 改为带 Authorization 头的 fetch + Blob 下载(自动还原中文文件名),修复点击下载提示"未认证"的问题。测试覆盖:《测试用例.md》83 条全部通过(Playwright 自动化)——§0 入口与通用 7、§1 导入 50(步骤一 6/步骤二 17/步骤三 4/执行结果 23)、§2 导出 15、§3 任务管理 14、§4 权限管理 13;另完成 M2/M3/附件 API 回归 42 断言无回归。50 万行导入 43s、100 万行导出 41s,性能达标。
测试中发现并修复的 15 个产品缺陷:
环境/测试基建:demo 集合群(customers/products/orders/tags/departments/devPK/usersTags 中间表)+ 测试员A/数据导入员角色 + 菜单路由角色授权(roles.desktopRoutes:set)+ 50 万行/错误数据/附件包测试文件 + Playwright E2E 套件(/tmp/opencode/e2e/,含 helpers 与 t0-t4 五节脚本)。
Sjgl02BlockModel(直接继承 BlockModel,自动落入"其他区块"分类),区块名"数据管理02-sjgl02",渲染导入/导出/任务管理 3 Tab(复用设置页组件,showPermissionTab=false 隐藏权限管理)。_previousDataValues 旧值快照,afterCreate/afterUpdate/afterDestroy 自动写 sjgl02PermissionLogs(before/after 全量快照 + 智能 summary:新增/修改(定位到变更字段)/移除/开关切换)。permTargets(用户+角色列表含角色摘要)、permList(自定义权限 + 按角色分组的继承权限,admin/root 角色特殊标记)。sjgl02:collectionMeta(字段元数据:类型/选项/关联目标/主键);修复 GET 接口参数合并(values 空对象遮蔽 query 参数);field-meta 排除 belongsTo/hasOne 的 foreignKey 属性列(ownerId 不再误当独立字段)。stats(状态聚合统计)、download(导出文件/导入源文件,流式 + RFC5987 中文文件名)、exportErrorReport(CSV,BOM + withoutDataWrapping)、retry(按 params 快照重建任务)、getScope/setScope(任务查看范围)。sjgl02UserSettings 表(userId 唯一 + taskScope);任务列表/详情按查看范围过滤(resourcer 中间件,非"查看全部"用户仅见自己任务;下载/错误报告同鉴权)。/v/admin/settings/sjgl02,4 Tab 容器),统计卡 6 张(点击快捷过滤)、类型/状态/关键词筛选、任务表格(进度条/操作列)、详情抽屉(KPI 网格/配置斑马纹/字段映射/导出字段/数据预览/失败明细分页加载/下载区)、进行中任务抽屉 2s 轮询、列表 5s 轮询、取消(回滚提示)/重新导出。getExportPermissions、exportableCollections(含 isAdmin 标记)、export(exportFilter 后端强制合并、字段白名单校验、全部表模式仅 admin/root)。主表字段名称(标识)-关联表名称(标识)(31 字符截断)。attachments/<字段标识>/<标题.扩展名> 打包 tar.gz(重名加 id 前缀)。全部数据表-时间戳.tar.gz。数据表名称-数据表标识-年月日时分秒.xlsx;多文件/含附件自动打 tar.gz;任务记录写入 filePath/fileName/fileSize。pack.entry(header, cb) 返回可写流需 source.pipe(entry),误用 v1 API(stream 作参数)导致打包死锁。sjgl02 自定义资源):importUpload(koaMulter 上传 Excel/附件包,返回 sheet 列表)、previewExcel(前 10 行预览)、getImportPermissions、importableCollections(按权限过滤可导入表)、import(行数/模式/白名单/唯一值校验后创建任务)、downloadTemplate(附件包模板)。attachments/<字段标识>/<文件名> 解包,提交前校验文件存在性与扩展名黑名单(缺失即回滚),数据提交后异步建附件记录(local 存储)并关联。yarn pm create 生成标准脚手架并与既有文档/元数据合并(src/server、src/client-v2、src/locale、入口 shim)。sjgl02Tasks(任务表)、sjgl02Permissions(权限配置表,含 targetType+targetId+collectionName 唯一索引)、sjgl02PermissionLogs(操作日志表),json 字段统一 jsonb。app.eventQueue 进程内调度(串行并发 1)+ AbortController 取消 + 进度节流写库(500ms);启动恢复(afterStart 将残留 pending/running 标记 failed"服务重启中断")。pm.sjgl02.import/export/tasks/permission),M1 阶段任务接口先放开 loggedIn。yarn nocobase upgrade 同步 3 表 14 索引成功。yarn build @my-project/plugin-sjgl02 --no-dts。docs/archive/。exceljs、tar-stream(不引入 bull / ioredis-mock,零新增队列依赖,生产环境装上即用)。2.1.1(2026-07-28)
@nocobase/app 入口后,经 Gateway.run → runAsCLI → loadCommands 加载所有插件 commands 文件,某第三方/Pro 插件 commands 文件 importModule 返回非函数导致 callback is not a function,loadCommands 整体失败,sjgl02:run-task 命令无法注册,worker 启动即失败,任务永远卡在 PENDING。
worker-entry.ts,不经过 Gateway.run() 和命令系统,直接 new Application() → app.load() → executeAsWorker(taskId),彻底绕过 loadCommands;worker-task-runner.ts 的 worker 入口从 @nocobase/app/lib/index.js 改为插件自己的 worker-entry.js;executeViaWorker 在启动 worker 前将任务状态从 PENDING 改为 RUNNING(与 execute 进程内路径保持一致),确保 worker 启动失败时 ensureNotRunning 的 filter 能正确匹配;ensureNotRunning 与 cancel 路径的 filter 从 { status: RUNNING } 改为 { status: [RUNNING, PENDING] }(双保险),确保任何中间状态都能被正确清理为 FAILED/CANCELED,不再卡在"排队中"。plugin-async-task-manager 的 CommandTaskType 机制,行数 ≥ 5 万的导入(提交时记录 plannedRows)与「全部数据表」导出任务改由 WORKER_MODE='-' 瞬态 NocoBase 子应用线程执行,大任务的 CPU 密集工作彻底移出主进程事件循环;小任务维持进程内执行(方案 A 让出已覆盖)。
server/commands/run-task.ts(sjgl02:run-task --taskId,.preload() 触发完整应用加载;手动加载 DB 动态集合;命令结束显式 process.exit 防止线程残留卡死队列);WorkerTaskRunner(spawn/取消先 IPC 优雅回滚 30s 超时强杀/异常退出兜底标记失败);task-queue 增加混合调度(shouldRunInWorker)与 executeAsWorker worker 入口;@nocobase/plugin-file-manager 的 server/commands/repair-filenames 缺 default export,导致 runAsCLI(worker 链路依赖)报 callback is not a function,已在该插件源码补 default export 并重新构建(属官方代码,升级官方版本时注意回归)。你安装完之后 要先重启系统 在开启插件
我测试 2.1.9和2.1.31版本 2.1.30版本都没问题
我也遇到了,请问下解决了吗
我系统内重启过了还是无法启用,我是通过docker部署的2.1.0-alpha39版本,必须要重启服务器才可以吗,服务器还没有尝试过
我没有解决这个插件的问题,我用AI简单写了个导出插件,临时解决了导出附件的问题。
搞定了,确实需要重启服务,不能只是系统内重启
你重启容器服务就行了
?.state?.currentUserId 改为 ?.state?.currentUser?.id(NocoBase 注入的是 ctx.state.currentUser.id);前端 getPermLogs 添加 appends: ['createdBy'];操作人列改为显示 createdBy.nickname/username。PermCardList 卡片摘要/详情弹窗、PermLogTable 变更详情中的字段显示统一为「字段名称(字段名)」格式,通过异步加载 getCollectionMeta 构建 name -> title 映射缓存。fieldLabel 显示「字段名称(字段名)」格式。sjgl02:permListByCollection 支持按表名查询所有配置。export.ts 中 permissionLabel 引用了 else 块内的 const config,块级作用域不可达。改为在外层 let 声明,else 块内赋值。sjgl02Tasks 集合定义中缺少 permissionLabel 字段,数据库表没这列,后端存的 permissionLabel 写不进去。已添加字段定义,部署后需执行 yarn nocobase upgrade 同步表结构。importFields/exportFields 顺序,之前在导入步骤2和导出步骤2中被忽略(只做白名单过滤,按 meta.fields 原始顺序)。现已改为:白名单非空时按权限配置的字段顺序排列字段。
useImportableFields 按 importFields 数组顺序重排字段映射表groups 组内按 exportFields 数组顺序重排字段列表getPkName 处理复合主键(filterTargetKey 为数组)的情况,取第一个字段作为游标,修复 sortKey.startsWith is not a function。existCache 缓存(相同唯一值组合不重复查库),系统字段 userId 校验改用缓存(同一用户只查一次);BATCH_SIZE 从 500 提升到 2000;附件处理预查询 storage 信息(从每文件查一次改为全局查一次)。1 万行 upsert 预计从 27 分钟降至 1-3 分钟。#1 (user) 改为显示友好名称(如 👤 小王),后端冗余存储 permissionLabel。run-task.ts 中 app.pm.get(PluginSjgl02Server) 构造函数引用查找改为字符串名称查找 app.pm.get('@my-project/plugin-sjgl02'),与 worker-entry.ts 保持一致,避免模块引用不一致导致查找失败。Collapse 折叠面板,默认展开,可手动收起;面板标题显示数量,搜索时保持展开。ChipsSelect 组件添加 showSearch 关键字搜索(按字段名称/标识过滤)和「全选」「清空」快捷按钮,字段多时可快速定位和批量操作。安装成功后升级的时候出错
Migration 20260725120000-drop-legacy-1x-tables/@my-project/plugin-sjgl02 (up) failed: Original error: (conn=23691, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘“sjgl02_permissions_created_by_id”’ at line 1
sql: DROP INDEX IF EXISTS “sjgl02_permissions_created_by_id” - parameters:: (conn=23691, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘“sjgl02_permissions_created_by_id”’ at line 1
sql: DROP INDEX IF EXISTS “sjgl02_permissions_created_by_id” - parameters:
哪个版本升级哪个版本 nocobase什么版本 什么数据库
2.2.6(2026-07-31)
model.update WHERE 条件从复合唯一值(订单号+商品编码,无索引时全表扫描 16 万行,155ms/行)改用主键 ID(WHERE id = ?,走主键索引,3ms/行)。1.9 万行 upsert 预计从 54 分钟降至约 1 分钟。使用 collection.model.primaryKeyAttribute 动态获取主键字段名,不依赖硬编码 id。activeKeys 变量定义但未更新引用处,导致页面崩溃。已改为直接硬编码 defaultActiveKey={['users', 'roles']}。Collapse 的 items API 对 children 做了内部 memoization,导致 onDragEnd/onMove/onRemove 回调闭包过期,引用旧的 state.selectedFields,操作无效。改为 Collapse.Panel 子组件方式,确保每次渲染重建闭包。window.dispatchEvent + useEffect 机制,改为 onJumpTo 回调直接传组内目标索引,调用处做全局索引转换(与 onDragEnd/onMove 统一逻辑)。SortableExportRow 序号编辑后 dispatch 事件但父组件无监听,导致输入序号回车后行不跳转。已添加 useEffect 监听 sjgl02-export-row-move 事件。SortableRow.commitMove 既调用 onMove(移一格)又 dispatch 事件(跳到目标),双重触发导致移动错乱。已删除 onMove 调用,只保留事件跳转。toolbarButtons 的 copyFromConfig 参数改为 'import'/'export' 字符串,正确区分目标区域。permissionLabel;增加原任务状态校验(仅失败/已取消可重试)。👥 统一为 🔐,与导出一致。executeViaWorker 已写过),避免 startedAt 被覆盖。fieldLabel 函数抽到独立文件 field-utils.ts,消除 ImportStep2 与 MappingTable 的循环依赖。TargetSidebar 删除无意义的三元表达式(两分支结果相同)。repo.update()(经 NocoBase 中间件链,68ms/行)改为 model.update(..., { hooks: false })(直接 Sequelize,3ms/行)。通过 rawAttributes 过滤非数据库列(关联数组),排除 createdById/createdAt。有 appendFields 时自动降级为原路径。create 路径不变(需要 hooks 生成 ID/加密密码)。1.9 万行 upsert 预计从 22 分钟降至约 1 分钟。性能日志中标注"快速"/"慢速"路径。previewRows 保存的是对象({field: value}),前端按数组索引取值导致 Excel 列值全部为空。改为按字段名从对象取值。writeLog 未传 context 给 create,NocoBase 的 createdBy: true 机制无法注入操作人。改为传 options.context,让框架自动注入。Card 改为 Collapse,默认收起,标题显示权限名称+模式简要,点击展开看详情。findOne 查询改为分批预加载(每 2000 行一批),用一条 WHERE field IN (...) 批量查询已存在的记录构建内存 Map,后续逐行从 Map 中查找。1.9 万行 upsert 预计从 16+ 分钟降至 30 秒左右。
PRELOAD_CHUNK = 2000 常量和 processUpsertChunk 方法;WHERE IN 预加载,内存中按完整组合精确匹配;appends(追加更新的关联字段)。