lml
|
6907bf5056
|
feat(core): 新增租户上下文与 404 异常,缓存键增加租户维度
- TokenData 新增 currentTenantId()/currentAppCode():A 端取登录租户,
B 端及无请求上下文(MQ、定时任务)返回 null
- 新增 DataNotFoundException,MyExceptionHandler 统一映射为 HTTP 404 +
DATA_NOT_EXIST,避免用 403 暴露资源是否存在
- CacheKey 的 FORM_HEAD_TABLE / FORM_HEAD_BY_TABLE_ID /
FORM_HEAD_TABLE_NAME / FORM_CHILD_FIELD / FORM_ONETOMANY_TABLE /
FORM_FIELD_BY_HEAD_Id 增加租户段(A 端 tenantId,B 端 base),
避免管理端复制来的相同 id 在租户之间互相覆盖缓存
|
1 day ago |
lml
|
a1c7bc8dc8
|
fix(botp): 打通「转换 → 手动保存 → 反写」链路并修复反写失效
- 移除转换时的反写触发:删除 ConvertOrchestrator#triggerSaveWriteBack 及其
WriteBackOrchestrator 依赖。转换只负责「源单 → 目标单」的数据复制,原实现在 autoSave
落库后补触发反写,等于把刚复制过去的值按规则再写回来,累加类公式让源单数量指数增长
(1→2→4→8→24),覆盖类公式把源单字段改成复制值。反写改由目标单被真正操作时触发,
入口已存在:SaveOperationServicePlugIn(保存)、AuditOperationServicePlugIn(审核),
时机由 reverse_writing_rules.trigger_timing 决定('1' 保存 / '2' 审核)
- 转换关系改用落库后的真实主键:BotpService#addNew 落库前收集分录「预发主键 → 对象实例」,
落库后读真实主键建立映射,saveRelation 用它覆盖 targe_entry_id。根因是
initDestBillData 建骨架时预发主键,而 ormGenDataSourceUtil.addNew 插入分录时会重新发号,
关系表存的是库里不存在的 id,反写按 targe_entry_id 查目标分录必然为空而静默跳过。
新增 BtpTransformResult#entryIdMap 承载映射,校正时打 INFO 记录「计划id / 实际id」
- 批量保存回写真实主键:新增 syncSavedIds,exePlugin 落库后把 ORM 回写的真实主键同步回
入参 JSON(表头直接覆盖,分录按 key 顺序 + 行下标对齐,与 getObjectValue 的入栈顺序一致)。
不回写的话 executeBatchSaveInTransaction 补写 convert_relation 时用预发 id,
关系指向不存在的记录,用户改单保存触发反写就会「找不到关联关系」。
实测:payload 里 header id=...101824 / entry id=...101825,
库里实际 ...04651520 / ...34011648
- 新增转换关系补写门面:BotpConvertRelationFacade(common-core 接口)+
ConvertRelationFacade(common-botp 实现),按 BillRelation JSON 补写
convert_relation / convert_relation_entry,target_id 以落库后真实主键覆盖,按主键幂等。
为什么需要:convert_relation 只在 BotpService#transform 的 autoSave 分支写入,
formStatus=2(未落库、前端手动保存)时转换阶段不写关系,保存后反写找不到来源单。
ConvertedBill 新增 billRelation,buildBatchSavePayload 内嵌到 masterData[i].billRelation,
父子关系由结构而非下标保证;executeBatchSave 摘出该键(不能当表头字段交给 ORM)。
executeBatchSaveInTransaction 增加 relationList 参数,落库后调 saveRelationQuietly 补写,
与保存在同一事务内。BotpReverseWriteSupport 泛化 getFacadeQuietly 支持按类型取门面,
未挂载 botp 的应用静默跳过
- 修正反写公式读写方向:formula(formulaEnglish) 指回写位置(源单),
sourceSingleField 指取值位置(目标单),原实现写反了,表现为「反写执行了但源单没变」。
变量统一改为 read(目标单,取值)/ write(源单,回写),避免后续再被读反
- 新增 isHeadTable:公式引用表头字段时用单据 id 查,引用分录字段时用分录行 id 查。
原先一律用分录 id,配成 请购单.请购单.供应商 这类表头字段时永远查不到行
- 新增 syncNonNumericValue:供应商、名称等文本字段无法做 BigDecimal 运算
(toBigDecimal 返回 null,nullToZero 后变成 0),改为正向直接把目标单值写到源单,
回滚按 before_value 恢复;目标单字段为空时跳过并告警,不把源单写空
- recordBeforeValue 改用 LambdaUpdateWrapper 显式 set:beforeValue 为 null 时
MyBatis-Plus 会跳过 null 字段,生成 UPDATE ... WHERE id=? 这种无 SET 的非法 SQL
- 新增 resolveEntryTableQuietly(key 兼容 tableId 与表名,解析不到返回 null 不抛)
与 toJsonRowList(分录值兼容数组与单行对象),用于主键回写
- 反写跳过日志补上表名与行 id,原先只打 id,无法判断查的是表头还是分录
- 新增 zz-resource/db-scripts/2026-10-27-convert-relation-entry-writeback-script.sql:
补 convert_relation_entry 的 before_value(decimal(24,8))与 writeback_rule_version(int)。
实体早已声明这两个字段(注释也写明「需要新增列」)但 DDL 未跟上,MyBatis-Plus 按实体
拼 SELECT,任何查询该表的 SQL 都会报 Unknown column 'before_value' in 'field list',
反写与转换落库都会直接失败。脚本用 information_schema 判断列是否存在,可重复执行
|
2 days ago |
chenchuchuan
|
da2be26f9c
|
refactor(botp): 重构字段映射策略体系与插件兼容机制
- 将映射策略接口改为按单行目标+源行组求值,解耦编排层与策略层
- BotpMappingContext 由 if/else 工厂改为 EnumMap 策略工厂,修复未知取值方式抛 NPE 的问题
- 各策略实现改为 Spring bean,依赖通过 @Resource 注入替代手工 getBean
- 新增按条件取值策略(BotpMappingStrategyCondition),复用在线规则引擎求值
- AbstractTransformPlugIn 改为实现 ConvertPlugIn 接口的兼容桥,存量插件无需改代码
- 回写插件分录表名从映射计划动态获取,修复 Long 对象引用比较的 bug
- 新增 BotpMappingException 替代 NPE,提供含配置原值的可读报错
- 抽取 BillDataConverter 工具类,编排器与兼容入口共用单据数据转换逻辑
|
1 week ago |
chenchuchuan
|
dffc4f8f39
|
feat(mcp-auth): 添加 MCP 端点鉴权拦截器与人员密钥管理
- 新增 McpAuthInterceptor,支持 Bearer JWT 与人员密钥两种鉴权方式
- 定义 McpAuthService、McpAccountProvider 等 SPI 契约,由应用侧实现
- 新增 McpWebMvcConfig 自动注册拦截器,未实现 SPI 时 fail-closed 返回 401
- 新增 SysUserSecret 实体及完整 CRUD,支持密钥签发、轮换、启停
- 实现凭证校验逻辑:keyId 定位、状态与有效期检查、SHA-256 摘要比对、手机号绑定校验
- 为 McpStreamableController 和 McpToolConfig 添加 apelet.mcp.enabled 开关控制
- 非管理员只能查看和操作自己的密钥,响应中不返回 secretHash 并脱敏手机号
|
2 weeks ago |
chenchuchuan
|
c10afd0cbe
|
feat(mcp): 添加MCP工具管理员权限控制与端点鉴权
- 在 McpToolScanner 中增加管理类工具前缀配置,命中前缀的工具仅允许管理员调用
- 调用时优先复用请求上下文中的 TokenData,避免覆盖真实身份导致匿名执行
- 新增 buildDefaultTokenData 方法作为无请求上下文时的兜底
- 实现 isToolAllowed 与 isAdminOnlyTool 方法进行工具级授权判断
- 在 InterceptorConfig 中注册 McpAuthInterceptor,独立处理 MCP 端点鉴权
- 将 MCP 端点路径从主登录态拦截器中排除,避免密钥调用被 401 拦截
- common-botp 模块依赖版本更新,common-core 版本改为引用变量
- 在 common 父模块中注册 common-botp 子模块
|
2 weeks ago |
chenchuchuan
|
b8e9998ec8
|
feat(online): 新增导入导出功能相关枚举和工具类
- 添加ImportAttrEnum、ImportExportEnabledStatus、ImportWriteModeEnum枚举类
- 实现ImportExportExcelUtil工具类,支持导入模板生成和文件下载
- 添加ImportExportFileCleanTimer定时清理任务
- 在OnlineConstant中增加导入导出模板缓存key相关方法
- 扩展OnlineDataSourceUtil提供IN条件查询功能
- 定义OnlineExportDataService接口及其实现类OnlineExportDataServiceImpl
- 修复ObjectValue类中类型转换可能引发的ClassCastException问题
|
1 month ago |
chenchuchuan
|
4aa8edb542
|
feat(mcp): 完善MCP工具参数解析支持嵌套对象数组
- 实现List<E>中E为带@McpToolParam对象时按对象展开items功能
- 添加hasMcpToolParamFields方法判断类型是否需要递归展开
- 优化toObject方法支持Map类型直接返回原参逻辑
- 扩展OnlineQuickFormField模型添加McpToolParam注解映射
- 增强OpenApiApp和OpenApiConfig模型的参数描述细节
- 重构OpenApiAppController集成McpToolClass工具类标注
- 添加LayoutType排版类型常量字典及校验方法
- 更新OnlineFormDto中表单类型和排版类型的详细描述
- 优化OpenApiAuthService中的应用凭证校验逻辑
- 新增removeAppWithRelationCheck服务方法检查关联关系后删除
- 调整OpenApiConfigController返回OpenApiConfigVo视图对象
- 修复MyBatis查询中LIKE语句安全拼接问题
|
2 months ago |
chenchuchuan
|
a0eb74ecd8
|
feat(common-openapi): 添加OpenAPI第三方应用管理和认证功能
- 新增OpenApiApp实体类及对应的数据库映射
- 实现OpenApiAppService服务接口及具体业务逻辑
- 添加OpenApiAppController控制器提供应用CRUD操作
- 实现OpenApiAuthService服务进行token签发与验证
- 添加OpenApiAuthController提供对外认证接口
- 创建OpenApiAuthInterceptor拦截器进行token校验
- 升级common-core版本至1.0.1并更新依赖引用
- 将exeListPlugin方法从Controller移至OnlineOperationService
- 移除OnlineOperationController中的废弃导入和私有方法
- 新增OpenApiConfig模型类用于存储接口配置信息
|
2 months ago |
chenchuchuan
|
3e25f370b8
|
feat(mcp): 添加MCP工具框架支持包括流式HTTP传输和注解扫描功能
- 新增 McpStreamableController 提供流式HTTP单端点支持 /tenantadmin/mcp
- 实现 StreamableHttpServerTransportProvider 支持MCP协议的流式HTTP传输
- 添加 @McpToolClass 和 @McpToolParam 注解用于标记MCP工具方法和参数
- 开发 McpToolScanner 扫描器自动注册带有注解的工具方法
- 集成 mcp-java8-sdk 依赖支持MCP协议服务器功能
- 新增 McpToolArgInfo 和 McpToolParamType 模型类处理工具参数元信息
- 配置 McpToolConfig 自动装配SSE和流式HTTP两种传输方式
- 为 MyPageParam 添加 MCP 参数注解支持分页参数映射
|
2 months ago |
sunquan
|
020d8c41eb
|
add:新增加common-core 模块
|
2 months ago |