树形下拉组件数据查询覆写

一、背景与问题

Oinone 的树形下拉组件(TreeSelect)和树视图(Tree)在查询数据时,最终调用的是树节点所配置模型的数据管理器函数:

树接口 调用的数据管理器函数 场景
fetchAll queryListByWrapper 一次性全量加载
fetchChildren queryPage 按层级懒加载(默认)
queryKeywords4Tree queryListByWrapper 关键字搜索
reverselyQuery queryListByWrapper 已选数据回填

官方文档原文:「所有树查询接口都会调用模型对应的数据管理器函数,可以通过重写的方式修改其查询结果。」

直接覆写的风险

如果直接在原模型(如 business.PamirsDepartment)上覆写 queryPage

// ⚠️ 危险写法:会影响所有使用 PamirsDepartment.queryPage 的场景
@Component
@Model.model(PamirsDepartment.MODEL_MODEL)
public class DeptQueryAction {

    @Function.Advanced(type = FunctionTypeEnum.QUERY, category = FunctionCategoryEnum.QUERY_PAGE)
    @Function.fun(FunctionConstants.queryPage)
    @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API})
    public Pagination<PamirsDepartment> queryPage(Pagination<PamirsDepartment> page, IWrapper<PamirsDepartment> queryWrapper) {
        // 追加过滤条件...
        return new PamirsDepartment().queryPage(page, queryWrapper);
    }
}

该覆写会全局生效——不仅是树形下拉,所有调用 PamirsDepartmentqueryPage 的地方(组织架构页面、人员管理列表、权限分配、框架内部关联查询等)都会受到影响,容易引发难以排查的副作用。

二、推荐方案:代理模型(PROXY)隔离

核心思路

  1. 创建一个继承原模型的代理模型ModelTypeEnum.PROXY),拥有独立的模型命名空间
  2. 在代理模型中重新声明自关联字段(如 parent),将关联目标指向代理模型自身
  3. 在代理模型的 Action 中覆写数据管理器函数,追加树形场景专属的过滤逻辑
  4. 树形下拉的视图 DSL 中,<node>model 指向代理模型

代理模型与原模型共享同一张数据表,但函数注册在各自独立的命名空间下,互不干扰。

框架官方示例

Oinone 框架自身就采用了这一模式:ResourceRegionProxyModel 继承 ResourceRegion,用于地区页面的代理展示,其扩展点 ResourceRegionProxyModelExtPoint 中的 queryPageAfter 只影响代理模型自身的查询。

三、完整实现步骤(以 PamirsDepartment 为例)

场景假设

业务需求:某个表单页面的「部门」树形下拉只需要展示当前公司companyCode == 当前用户公司)且启用状态dataStatus == ENABLED)的部门,而系统中其他使用 PamirsDepartment 的地方(组织架构、权限管理等)不受影响。

步骤 1:定义代理模型

package com.example.demo.model;

import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.enmu.ModelTypeEnum;
import pro.shushi.pamirs.business.api.model.PamirsDepartment;

import java.util.List;

/**
 * 部门树形下拉专用代理模型
 * <p>
 * 继承 PamirsDepartment,共享同一张数据表,
 * 但拥有独立的函数命名空间,覆写 queryPage 不影响原模型。
 */
@Model.model(DeptTreeProxy.MODEL_MODEL)
@Model.Advanced(type = ModelTypeEnum.PROXY)
@Model(displayName = "部门(树选择)", labelFields = "name")
public class DeptTreeProxy extends PamirsDepartment {

    public static final String MODEL_MODEL = "demo.DeptTreeProxy";

    /**
     * 【必须重新声明】上级部门(自关联字段)
     * <p>
     * 基类 PamirsDepartment 中 parent 的类型是 PamirsDepartment,
     * 代理模型必须将其覆盖为指向自身(DeptTreeProxy),
     * 否则设计器/树组件无法在代理模型命名空间内构成完整的自关联关系,
     * 导致树形下拉无法正确展开层级。
     */
    @Field.many2one
    @Field.Relation(relationFields = {"parentCode"}, referenceFields = {"code"})
    @Field(displayName = "上级部门")
    private DeptTreeProxy parent;

    /**
     * 【必须重新声明】下级部门(自关联 O2M 字段)
     * <p>
     * 与 parent 对应,保持自关联关系的双向完整性。
     */
    @Field.one2many
    @Field.Relation(relationFields = {"code"}, referenceFields = {"parentCode"})
    @Field(displayName = "下级部门")
    private List<DeptTreeProxy> childList;
}

要点说明:

  • ModelTypeEnum.PROXY:标记为代理模型,不会新建数据表,底层复用父模型的表
  • MODEL_MODEL 使用项目自己的命名空间(如 demo.),与框架的 business. 隔离

⚠️ 关键陷阱:自关联字段必须重新声明

基类 PamirsDepartmentparent 字段的类型是 PamirsDepartment,其关联关系指向 business.PamirsDepartment
如果代理模型不重新声明 parent,则树组件在解析 selfReferences="parent" 时,
发现该字段的关联目标不是当前代理模型(demo.DeptTreeProxy),而是父模型(business.PamirsDepartment),
导致设计器页面和树形下拉无法构成完整的自关联树结构,表现为:树只有一层、无法展开子节点、或报错。

因此,所有构成树形结构的自关联字段(M2O 的 parent 和 O2M 的 childList)都必须在代理模型中重新声明,将类型指向代理模型自身。

步骤 2:在代理模型 Action 中覆写数据管理器函数

package com.example.demo.action;

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.framework.connectors.data.sql.query.LambdaQueryWrapper;
import pro.shushi.pamirs.framework.connectors.data.sql.query.QueryWrapper;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.api.dto.condition.Pagination;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.constant.FunctionConstants;
import pro.shushi.pamirs.meta.enmu.FunctionCategoryEnum;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;
import pro.shushi.pamirs.core.common.enmu.DataStatusEnum;
import com.example.demo.model.DeptTreeProxy;

import java.util.List;

/**
 * 部门树形下拉代理模型的查询动作
 * <p>
 * 覆写 queryPage 和 queryListByWrapper,
 * 仅对树形下拉组件的查询生效,不影响 PamirsDepartment 原模型。
 */
@Component
@Model.model(DeptTreeProxy.MODEL_MODEL)
public class DeptTreeProxyAction {

    /**
     * 覆写分页查询 —— 树组件懒加载(fetchChildren)时调用
     *
     * @param page         分页参数
     * @param queryWrapper 框架自动构建的查询条件(已包含树层级关联条件)
     * @return 过滤后的分页结果
     */
    @Function.Advanced(type = FunctionTypeEnum.QUERY, category = FunctionCategoryEnum.QUERY_PAGE)
    @Function.fun(FunctionConstants.queryPage)
    @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API})
    public Pagination<DeptTreeProxy> queryPage(Pagination<DeptTreeProxy> page,
                                               QueryWrapper<DeptTreeProxy> queryWrapper) {
        // 将 QueryWrapper 转为 LambdaQueryWrapper,通过方法引用指定字段,避免硬编码列名
        LambdaQueryWrapper<DeptTreeProxy> wrapper = queryWrapper.lambda();
        // 追加业务过滤条件:只展示启用状态的部门
        wrapper.eq(DeptTreeProxy::getDataStatus, DataStatusEnum.ENABLED);
        // 追加业务过滤条件:只展示当前用户所属公司的部门
        String companyCode = PamirsSession.getContext().getCompanyCode();
        wrapper.eq(DeptTreeProxy::getCompanyCode, companyCode);
        // 调用代理模型的默认数据管理器执行查询
        return new DeptTreeProxy().queryPage(page, wrapper);
    }

    /**
     * 覆写列表查询 —— 树组件全量加载(fetchAll)和搜索(queryKeywords4Tree)时调用
     *
     * @param queryWrapper 框架自动构建的查询条件
     * @return 过滤后的列表结果
     */
    @Function.Advanced(type = FunctionTypeEnum.QUERY)
    @Function.fun(FunctionConstants.queryListByWrapper)
    @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API})
    public List<DeptTreeProxy> queryListByWrapper(QueryWrapper<DeptTreeProxy> queryWrapper) {
        // 将 QueryWrapper 转为 LambdaQueryWrapper
        LambdaQueryWrapper<DeptTreeProxy> wrapper = queryWrapper.lambda();
        // 追加与 queryPage 相同的业务过滤条件
        wrapper.eq(DeptTreeProxy::getDataStatus, DataStatusEnum.ENABLED);
        String companyCode = PamirsSession.getContext().getCompanyCode();
        wrapper.eq(DeptTreeProxy::getCompanyCode, companyCode);
        return new DeptTreeProxy().queryListByWrapper(wrapper);
    }
}

要点说明:

  • @Function.fun(FunctionConstants.queryPage):将方法注册为代理模型命名空间下的 queryPage 数据管理器函数,覆盖默认实现
  • 树组件内部通过 Models.data().queryPage(pagination, queryWrapper) 调用时,pagination.model 已被设置为节点配置的模型编码,因此会自动路由到代理模型的覆写版本
  • 通过 queryWrapper.lambda() 转为 LambdaQueryWrapper,使用 DeptTreeProxy::getDataStatus 等方法引用指定字段,避免硬编码数据库列名,字段重命名时编译期即可发现错误
  • 方法体内调用 new DeptTreeProxy().queryPage(page, wrapper) 执行实际的数据库查询

步骤 3:配置树形下拉视图 DSL

在表单视图中,将 TreeSelect 字段的 <node> 指向代理模型:

<view model="业务模型编码" type="form" name="xxx_form_view">
  <template slot="form">
    <!-- 树形下拉字段:node 的 model 指向代理模型 -->
    <field data="department" label="部门" widget="TreeSelect" span="1">
      <nodes>
        <node label="activeRecord.name"
              model="demo.DeptTreeProxy"
              selfReferences="parent"
              searchFields="name" />
      </nodes>
    </field>
  </template>
</view>

DSL 关键属性:

属性 说明
model 树节点数据来源模型 —— 指向代理模型,这是隔离生效的关键
selfReferences 自关联字段名(parent),表示该模型通过 M2O 字段 parent 构成树
label 节点显示文本的表达式,activeRecord.name 表示取记录的 name 字段
searchFields 搜索时匹配的字段列表
filter 可选,RSQL 语法的静态过滤条件(简单场景可替代后端覆写)

步骤 4(可选):多级树节点配置

如果树形下拉需要「公司 → 部门」两级结构:

<field data="department" label="部门" widget="TreeSelect" span="1">
  <nodes>
    <!-- 第一级:公司 -->
    <node label="activeRecord.name" model="business.PamirsCompany" />
    <!-- 第二级:部门,通过 company 字段关联上级,parent 构成部门内自关联 -->
    <node label="activeRecord.name"
          model="demo.DeptTreeProxy"
          references="company"
          selfReferences="parent"
          searchFields="name" />
  </nodes>
</field>

四、方案对比

维度 直接覆写原模型 代理模型隔离(推荐) DSL filter 属性
影响范围 全局所有使用该模型查询的场景 仅树组件(指向代理模型的视图) 仅该视图的树节点
灵活性 高(可写任意 Java 逻辑) 高(可写任意 Java 逻辑) 低(仅支持 RSQL 静态条件)
副作用风险
适用场景 确实需要全局修改查询行为 特定页面/组件需要定制数据 简单的静态过滤

五、注意事项

  1. 自关联字段必须在代理模型中重新声明:基类的 parent(M2O)和 childList(O2M)字段的关联目标指向基类模型,代理模型必须用自身类型重新声明这些字段,否则设计器无法识别代理模型内的完整树形关联关系,树形下拉将无法正确展开
  2. queryPage 和 queryListByWrapper 都要覆写:树组件的懒加载走 queryPage,全量加载和搜索走 queryListByWrapper,只覆写一个会导致部分场景过滤失效
  3. 代理模型不建新表ModelTypeEnum.PROXY 类型的模型复用父模型的物理表,无需担心数据同步问题
  4. 使用 LambdaQueryWrapper + 方法引用指定字段:通过 queryWrapper.lambda() 转换后,使用 DeptTreeProxy::getDataStatus 等方法引用指定字段,避免硬编码数据库列名字符串,字段重命名时编译期即可发现错误
  5. 不要在覆写方法中调用 Models.data().queryPage():这会再次路由到函数注册中心,可能形成递归调用;应使用 new XxxProxy().queryPage(page, wrapper) 直接执行
  6. 简单过滤优先考虑 DSL filter:如果过滤条件是静态的(如 dataStatus == ENABLED),直接在 <node filter="..."> 中配置 RSQL 即可,无需写代码

Oinone社区 作者:nation原创文章,如若转载,请注明出处:https://doc.oinone.top/backend/25596.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
nation's avatarnation数式员工
Previous 2026年7月2日 pm4:53
Next 2024年6月20日 am9:49

相关推荐

  • 工作流引入流程概览与流程监控

    流程概览依赖说明 使用 流程概览 功能前,需要在项目中引入 pamirs-workflow-datavi-core、 pamirs-data-visualization-core依赖,并启动datavi模块: <dependency> <groupId>pro.shushi.pamirs.workflow</groupId> <artifactId>pamirs-workflow-datavi-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.data.visualization</groupId> <artifactId>pamirs-data-visualization-core</artifactId> </dependency> 警告: 在 oinone 平台启用「流程概览」能力时,应用启动模块一旦引入 pamirs-workflow-api/core,必须同时引入 pamirs-workflow-datavi-api/core。在多启动模块架构下,严禁出现仅部分启动模块引入 pamirs-workflow-core 而未引入 pamirs-workflow-datavi-core 的情况,否则将导致流程概览相关元数据计算异常,出现删表等情况。 流程概览配置项 流程概览页面内置缓存机制,可通过配置项调整缓存刷新周期及图表展示的数据条数: pamirs: workflow: dashboard: cache-time: 10 # 流程概览缓存刷新时间(单位:分钟),默认 10 分钟 page-size: 10 # 流程运行分析中 4 个图表的展示数量,默认查询前 10 条数据 统计指标说明 引入 pamirs-workflow-datavi-core 依赖后,系统会按照以下规则进行数据同步: 当日数据同步:每小时同步一次当日数据; 昨日数据同步:次日凌晨同步前一日数据。 由于在引入依赖后才会开始执行数据同步,统计指标页提供了「同步」按钮,可用于对历史数据进行补采。即使不执行历史同步,也不会影响核心业务流程,仅会影响统计数据和图表的展示效果。 统计指标数据主要用于 支撑 流程概览 和 流程监控 中的统计图表展示; 为数据分析与可视化提供基础数据。 上述统计数据对工作流的审批、流转等核心业务无任何影响。如有需要,也可以基于流程监控的数据,配合数据可视化设计器,自定义构建符合业务需求的展示页面。

    2025年11月17日
    59300
  • 【后端】项目开发后端知识要点地图

    目录 工程结构篇 协议篇 GraphQL请求:后端接口实现逻辑解析 基本功能及配置篇 Dubbo Dubbo配置详解 Nacos Oinone项目引入Nacos作为注册中心 Oinone项目引入Nacos作为配置中心 Nacos做为注册中心调用其他系统的SpringCloud服务 OSS OSS(CDN)配置和文件系统的一些操作 MINIO无公网访问地址下OSS的配置 Trigger/Async/Schedule 函数之触发与定时配置和示例 函数之异步执行 Excel导入/导出(file) Excel批量导入 【Excel导入/导出】多Sheet导入导出示例 如何自定义Excel导入功能 如何自定义Excel导出功能 Excel导入导出模板翻译 Expression(表达式) 扩展内置函数表达式 ShardingJDBC(分库分表) 分库分表与自定义分表规则 Elasticsearch(ES) Oinone引入搜索引擎(增强模型) 引入搜索(增强模型Channel)常见问题解决办法 数据库方言配置(Dialect) 【DM】后端部署使用Dameng数据库(达梦) 【PostgreSQL】后端部署使用PostgreSQL数据库(PGSQL) 【OpenGauss】后端部署使用OpenGauss数据库(高斯) 【MSSQL】后端部署使用MSSQL数据库(SQLServer) 【KDB】后端部署使用Kingbase数据库(人大金仓/电科金仓) 【Oracle】后端部署使用Oracle数据库 【OceanBase】后端部署使用 OceanBase 数据库(海扬/OB) 其他功能使用文档 框架之MessageHub(信息提示) DsHint(指定数据源)和BatchSizeHint(指定批次数量) IWrapper、QueryWrapper和LambdaQueryWrapper使用 查询时自定义排序字段和排序规则 如何在代码中使用自增ID和获取序列 非存储字段搜索,适应灵活的搜索场景 如何使用位运算的数据字典 全局首页及应用首页配置方法(homepage) 如何增加用户中心的菜单 自定义RSQL占位符(placeholder)及在权限中使用 Function、Action函数使用规范 特定场景解决方案 Oinone连接外部数据源方案 如何自定义SQL(Mapper)语句 工程部署 后端部署 Oinone平台部署及依赖说明 v4.7 v5.0 v5.1 v5.3 v6.2 Oinone License 许可证使用常见问题 后端无代码设计器Jar包启动方法 Oinone环境保护(v5.2.3以上) 设计器部署 Oinone设计器部署参数说明 Oinone离线部署设计器镜像 Oinone离线部署设计器JAR包 Docker部署常见问题 其他环境部署 东方通Web和Tomcat部署Oinone项目 可视化调试工具 Oinone平台可视化调试工具 协同开发 Oinone协同开发使用手册 工作流 项目中工作流引入和流程触发 【工作流】流程扩展自定义函数示例代码汇总 工作流-流程代办等页面自定义 工作流审核撤回/回退/拒绝钩子使用 如何添加工作流运行时依赖(前后端) 数据可视化运行时 如何添加数据可视化运行时依赖 界面设计器 如何实现页面间的跳转 界面设计器的导入导出 流程设计器 流程设计器的导入导出 数据可视化 数据可视化-项目中如何引用图表、报表、大屏 数据可视化中图表的低无一体 数据可视化-如何自定义查询数据方法 数据可视化的导入导出 其他 EIP开放接口使用MD5验签发起请求(v5.x) 缓存连接由Jedis切换为Lettuce Oinone登录扩展:对接SSO QA 导入设计数据时dubbo超时导入失败

    2024年10月23日
    4.2K00
  • 项目中常用的 Tools 工具类

    模型拷贝工具类 KryoUtils.get().copy(modelData); ArgUtils.convert(DataReport.MODEL_MODEL, DataDesignerReport.MODEL_MODEL, report); pro.shushi.pamirs.framework.common.utils.ObjectUtils#clone(T) Rsql工具类 RsqlParseHelper.parseRsql2Sql(queryWrapper.getModel(), rsql); RSQLHelper.getRsqlValues(sql.getOriginRsql(), fieldSet); 序列化工具类 后端使用的JSON序列化 JsonUtils.toJSONString(nodes); 前端使用的JSON序列化 PamirsJsonUtils.toJSONString(nodes, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.BrowserCompatible); 生成ID //根据模型生成id Long generate = (Long) Spider.getDefaultExtension(IdGenerator.class).generate(PamirsTableInfo.fetchKeyGenerator(Teacher.MODEL_MODEL)); //生成id Long l = Long.valueOf(UidGeneratorFactory.getCachedUidGenerator().getUID()); 权限相关 // 获取权限路径path AccessResourceInfoSession.getInfo().getOriginPath(); 其他 PamirsSession相关 PamirsSession.isAdmin() # 是否admin用户 PamirsSession.getUserId() # 获取登录用户ID PamirsSession.getRequestVariables() PamirsSession.getContext().getModelCache().get(PetShop.MODEL_MODEL).getTable(); # 获取模型信息 PamirsSession.getContext().getExtendCache(ActionCacheApi.class).get(Teacher.MODEL_MODEL, "importArchivesInfo") # 获取函数信息

    2025年5月8日
    1.2K01
  • 重写QueryPage时,增加额外的条件

    在需要对QueryPage增加额外的查询条件,比如DemoItem增加只展示创建人为当前用户的数据 @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "查询列表") @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API}) public Pagination<DemoItem> queryPage(Pagination<DemoItem> page, IWrapper<DemoItem> queryWrapper) { LambdaQueryWrapper<DemoItem> qw = ((QueryWrapper<DemoItem>) queryWrapper).lambda(); qw.eq(DemoItem::getCreateUid, PamirsSession.getUserId()); return demoItemService.queryPage(page, qw); }

    2023年11月1日
    1.1K00
  • Excel导入扩展点-整体导入(批量导入)

    1、【导入】在有些场景,需要获取Excel导入的整体数据,进行批量的操作或者校验 可以通过实现导入扩展点的方式实现,入参data是导入Excel的数据列表;业务可以根据实际情况进行数据校验 1)Excel模板定义,需要设置setEachImport(false) 2)导入扩展点API定义 pro.shushi.pamirs.file.api.extpoint.ExcelImportDataExtPoint#importData 3)示例代码参考: pro.shushi.pamirs.translate.extpoint.ResourceTranslationImportExtPoint#importData @Slf4j @Component @Ext(ExcelImportTask.class) public class ResourceTranslationImportExtPoint extends AbstractExcelImportDataExtPointImpl<List<ResourceTranslationItem>> { @Override //TODO 表达式,可以自定义,比如可以支持1个模型的多个【导入名称】的不同模板 @ExtPoint.Implement(expression = "importContext.definitionContext.model==\"" + ResourceTranslation.MODEL_MODEL + "\"") public Boolean importData(ExcelImportContext importContext, List<ResourceTranslationItem> dataList) { //TODO dataList就是excel导入那个sheet的所有内容 return true; } } 2、【导入】逐行导入的时候做事务控制 在模板中定义中增加事务的定义,并设置异常后回滚。参加示例代码: excel模板定义 @Component public class DemoItemImportTemplate implements ExcelTemplateInit { public static final String TEMPLATE_NAME = "商品导入模板"; @Override public List<ExcelWorkbookDefinition> generator() { //定义事务(导入处理中,只操作单个表的不需要事务定义。) //是否定义事务根据实际业务逻辑确定。比如:有些场景在导入前需要删除数据后在进行导入就需要定义事务 InitializationUtil.addTxConfig(DemoItem.MODEL_MODEL, ExcelDefinitionContext.EXCEL_TX_CONFIG_PREFIX + TEMPLATE_NAME); return Collections.singletonList( ExcelHelper.fixedHeader(DemoItem.MODEL_MODEL, TEMPLATE_NAME) .setType(ExcelTemplateTypeEnum.IMPORT) .createSheet("商品导入-sheet1") .createBlock(DemoItem.MODEL_MODEL) .addUnique(DemoItem.MODEL_MODEL,"name") .addColumn("name","名称") .addColumn("description","描述") .addColumn("itemPrice","单价") .addColumn("inventoryQuantity","库存") .build().setEachImport(true) //TODO 设置异常后回滚的标识,这个地方会回滚事务 .setHasErrorRollback(true) .setExcelImportMode(ExcelImportModeEnum.SINGLE_MODEL) ); } } 导入逻辑处理 @Slf4j @Component @Ext(ExcelImportTask.class) public class DemoItemImportExtPoint extends AbstractExcelImportDataExtPointImpl<DemoItem> implements ExcelImportDataExtPoint<DemoItem> { @Autowired private DemoItemService demoItemService; @Override @ExtPoint.Implement(expression = "importContext.definitionContext.model == \"" + DemoItem.MODEL_MODEL + "\"") public Boolean importData(ExcelImportContext importContext, DemoItem data) { ExcelImportTask importTask = importContext.getImportTask(); try { DemoItemImportTask hrExcelImportTask = new DemoItemImportTask().queryById(importTask.getId()); String publishUserName = Optional.ofNullable(hrExcelImportTask).map(DemoItemImportTask::getPublishUserName).orElse(null); data.setPublishUserName(publishUserName); demoItemService.create(data); } catch(PamirsException e) { log.error("导入异常", e); } catch (Exception e) { log.error("导入异常", e); } return Boolean.TRUE; } }

    2023年12月7日
    2.0K00

Leave a Reply

Please Login to Comment