工作流:通过业务数据操作工作流程(催办、撤销等)

一、抽象模型,需要操作流程的模型继承此模型

定义流程相关的一些信息在模型中;如果直接定义在存储模型中,下面这些字段都是显示的指定为非存储字段。更好的建议:
1、如果有多个业务模型有这类需要,则可以把这些字段抽取到抽象模型中
2、如果仅有一个业务模型需要,则可以放到代理模型中

/**
 * 定义流程相关的一些信息在模型中
 */
@Model.model(DemoBaseAbstractModel.MODEL_MODEL)
@Model(displayName = "抽象模型")
@Model.Advanced(type= ModelTypeEnum.ABSTRACT)
public abstract class DemoBaseAbstractModel extends IdModel {

    public static final String MODEL_MODEL = "hr.simple.DemoBaseAbstractModel";

    // 流程相关
    @Field.Integer
    @Field(displayName = "工作流用户任务ID", summary = "业务数据列表中审核流程使用", invisible = true, store = NullableBoolEnum.FALSE)
    private Long workflowUserTaskId;

    @Field.Integer
    @Field(displayName = "流程实例ID", summary = "业务数据列表中催办使用", invisible = true, store = NullableBoolEnum.FALSE)
    private Long instanceId;

    @Field.String
    @UxForm.FieldWidget(@UxWidget(invisible = "true"))
    @UxDetail.FieldWidget(@UxWidget(invisible = "true"))
    @Field(displayName = "当前流程节点", store = NullableBoolEnum.FALSE)
    private String currentFlowNode;

    @Field.Boolean
    @Field(displayName = "能否催办", invisible = true, defaultValue = "false", store = NullableBoolEnum.FALSE)
    private Boolean canUrge;

    // 审批状态控制申请单是否可以被发起流程、能否编辑等控制
    @Field.Enum
    @Field(displayName = "审批状态", defaultValue = "NC")
    @UxForm.FieldWidget(@UxWidget(invisible = "true"))
    private ApprovalStatusEnum approvalStatus;

}
@Dict(dictionary = ApprovalStatusEnum.dictionary, displayName = "审批状态")
public enum ApprovalStatusEnum implements IEnum<String> {
    NC("NC", "待提交", "待提交"),
    PENDING("PENDING", "已提交", "已提交,待审批"),
    APPROVED("APPROVED", "已批准", "已批准"),
    REJECTED("REJECTED", "已拒绝", "已拒绝");

    public static final String dictionary = "land.enums.LandApprovalStatusEnum";

    private final String value;
    private final String displayName;
    private final String help;

    ApprovalStatusEnum(String value, String displayName, String help) {
        this.value = value;
        this.displayName = displayName;
        this.help = help;
    }

    public String getValue() {
        return value;
    }

    public String getDisplayName() {
        return displayName;
    }

    public String getHelp() {
        return help;
    }
}

二、实现公共逻辑(催办、撤销)

@Slf4j
@Component
@Model.model(DemoBaseAbstractModel.MODEL_MODEL)
public class DemoBaseAbstractModelAction {

    @Autowired
    private WorkflowInstanceService workflowInstanceService;

    @Action(displayName = "催办", summary = "流程催办", bindingType = ViewTypeEnum.TABLE, contextType = ActionContextTypeEnum.SINGLE)
    @Action.Advanced(invisible = "!activeRecord.canUrge")
    public DemoBaseAbstractModel urge(DemoBaseAbstractModel data) {
        if (data.getInstanceId() == null) {
            return data;
        }

        WorkflowInstance instance = new WorkflowInstance().setId(data.getInstanceId()).queryById();
        workflowInstanceService.urge(instance);
        PamirsSession.getMessageHub().success("催办操作成功");
        return data;
    }

    @Action(displayName = "提交审核", bindingType = ViewTypeEnum.TABLE, contextType = ActionContextTypeEnum.SINGLE)
    @Action.Advanced(invisible = "activeRecord.approvalStatus != 'NC'")
    public DemoBaseAbstractModel submit(DemoBaseAbstractModel data) {
        data.setApprovalStatus(ApprovalStatusEnum.PENDING);
        data.updateById();
        PamirsSession.getMessageHub().success("提交审核成功");
        return data;
    }

    @Function(openLevel = FunctionOpenEnum.LOCAL)
    @Function.Advanced(type = FunctionTypeEnum.UPDATE, displayName = "审核通过")
    public DemoBaseAbstractModel applySuccess(DemoBaseAbstractModel data) {
        data.setApprovalStatus(ApprovalStatusEnum.APPROVED);
        data.updateById();

        return data;
    }

    @Action(displayName = "撤销", bindingType = ViewTypeEnum.TABLE)
    public DemoBaseAbstractModel undo(DemoBaseAbstractModel data) {
        if (data.getInstanceId() == null) {
            return data;
        }
        WorkflowInstance instance = new WorkflowInstance().setId(data.getInstanceId()).queryById();
        workflowInstanceService.undoInstance(instance.getId());

        data.setApprovalStatus(ApprovalStatusEnum.NC);
        data.updateById();

        return data;
    }

}

三 、定义业务模型

@Model.model(AssetsProxy.MODEL_MODEL)
@Model(displayName = "资产代理模型")
public class AssetsProxy extends DemoBaseAbstractModel {

    public static final String MODEL_MODEL = "land.mgmt.AssetsProxy";

    @Field(displayName = "使用单位")
    private String useUnit;

    @Field.String
    @Field(displayName = "统一社会信用代码")
    private String creditCode;

    @Field(displayName = "联系电话")
    private String contactNumber;

    @Field.String
    @Field(displayName = "申请单号", invisible = true)
    private String number;

}

四、业务数据逻辑

在业务表格中、通过自定义queryPage查询,将工作流实例ID、用户待办ID,动态的放到业务数据中,以便于实现催办、撤销逻辑。
如需只能自己发起的才能进行操作,这个条件可以在页面设计器上配置,也可以写到Action上,本文催办按钮在Action上定义。也可以在界面设计器设置按钮的隐藏条件(activeRecord.canUrge==true)

@Slf4j
@Component
@Model.model(AssetsProxy.MODEL_MODEL)
public class AssetsProxyAction {

    @Autowired
    private WorkflowUserTaskHandler workflowUserTaskHandler;

    @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "查询列表")
    @Function.fun(FunctionConstants.queryPage)
    @Function(openLevel = {FunctionOpenEnum.API})
    public Pagination<AssetsProxy> queryPage(Pagination<AssetsProxy> page, QueryWrapper<AssetsProxy> queryWrapper) {
        page = new AssetsProxy().queryPage(page, queryWrapper);
        workflowUserTaskHandler.computeWorkflowUserTask(page.getContent(), AssetsProxy.MODEL_MODEL);
        return page;
    }

    @Transactional
    @Action.Advanced(name = FunctionConstants.create, managed = true, invisible = ExpConstants.idValueExist)
    @Action(displayName = "保存", summary = "创建", bindingType = ViewTypeEnum.FORM)
    @Function(name = FunctionConstants.create)
    @Function.fun(FunctionConstants.create)
    public AssetsProxy create(AssetsProxy data) {
        data.setApprovalStatus(ApprovalStatusEnum.NC);
        data.construct();
        data.create();

        return data;
    }

    @Transactional
    @Action.Advanced(invisible = ExpConstants.idValueExist)
    @Action(displayName = "保存并发起流程", summary = "保存并发起流程", bindingType = ViewTypeEnum.FORM)
    public AssetsProxy saveAndSubmit(AssetsProxy data) {
        data.setApprovalStatus(ApprovalStatusEnum.PENDING);
        data.construct();
        data.create();

        // 代码触发工作流ID
        WorkflowD workflowD = new WorkflowD().setId(759036552176484888L).queryOne();
        if (workflowD != null) {
            startWorkflow(workflowD, data);
        }

        return data;
    }

    /**
     * 触发⼯作流实例
     */
    private Boolean startWorkflow(WorkflowD workflowD, IdModel modelData) {
        WorkflowDefinition workflowDefinition = new WorkflowDefinition().queryOneByWrapper(
                Pops.<WorkflowDefinition>lambdaQuery()
                        .from(WorkflowDefinition.MODEL_MODEL)
                        .eq(WorkflowDefinition::getWorkflowCode, workflowD.getCode())
                        .eq(WorkflowDefinition::getActive, 1)
        );
        if (null == workflowDefinition) {
            // 流程没有运⾏实例
            return Boolean.FALSE;
        }
        String model = Models.api().getModel(modelData);

        //⼯作流上下⽂
        WorkflowDataContext wdc = new WorkflowDataContext();
        wdc.setDataType(WorkflowVariationTypeEnum.ADD);
        wdc.setModel(model);
        wdc.setWorkflowDefinitionDefinition(workflowDefinition.parseContent());
        wdc.setWorkflowDefinition(workflowDefinition);
        wdc.setWorkflowDefinitionId(workflowDefinition.getId());
        IdModel copyData = KryoUtils.get().copy(modelData);
        // ⼿动触发创建的动作流,将操作⼈设置为当前⽤户,作为流程的发起⼈
        copyData.setCreateUid(PamirsSession.getUserId());
        copyData.setWriteUid(PamirsSession.getUserId());
        String jsonData = JsonUtils.toJSONString(copyData.get_d());
        //触发⼯作流 新增时触发-onCreateManual 更新时触发-onUpdateManual
        String msgId = UUIDUtil.getUUIDNumberString();
        Fun.run(WorkflowModelTriggerFunction.FUN_NAMESPACE, "onCreateManual", wdc, msgId, jsonData);
        return Boolean.TRUE;
    }

}
@Component
public class WorkflowUserTaskHandler<T extends DemoBaseAbstractModel> {

    public void computeWorkflowUserTask(List<T> datas, String model) {
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }

        // 过滤掉【草稿状态】和【审核通过】的数据,减少数据查询量
        List<Long> bizIds = ListUtils.transform(datas, DemoBaseAbstractModel::getId);
        LambdaQueryWrapper<WorkflowUserTask> userTaskWrapper = new LambdaQueryWrapper<>();
        userTaskWrapper.setModel(WorkflowUserTask.MODEL_MODEL);
        userTaskWrapper.select(WorkflowUserTask::getId, WorkflowUserTask::getNodeDataBizId, WorkflowUserTask::getUserId, WorkflowUserTask::getInitiatorUid,
                WorkflowUserTask::getNodeName, WorkflowUserTask::getNodeId, WorkflowUserTask::getInstanceId);
        userTaskWrapper.eq(WorkflowUserTask::getModel, model)
                .eq(WorkflowUserTask::getStatus, WorkflowUserStatusEnum.ACTIVE)
                .in(WorkflowUserTask::getNodeDataBizId, bizIds);

        Pagination<WorkflowUserTask> userTaskPagination = new Pagination<>();
        userTaskPagination.setCurrentPage(1);
        userTaskPagination.setSize(200L);
        userTaskPagination.setSort(new Sort().addOrder(SortDirectionEnum.DESC, WorkflowUserTask::getCreateDate));
        List<WorkflowUserTask> allUserTasks = new WorkflowUserTask().queryListByWrapper(userTaskPagination, userTaskWrapper);
        if (CollectionUtils.isEmpty(allUserTasks)) {
            return;
        }

        // 按NodeDataBizId分组,保留第一个出现的对象
        Map<Long, WorkflowUserTask> workflowUserTaskMap = allUserTasks.stream().filter(user -> user.getNodeDataBizId() != null)
                .collect(Collectors.toMap(WorkflowUserTask::getNodeDataBizId, user -> user, (existing, replacement) -> existing));
        // userTaskWrapper.eq(WorkflowUserTask::getUserId, PamirsSession.getUserId())
        List<WorkflowUserTask> userTasks = allUserTasks.stream().filter(task -> task.getUserId() != null && task.getUserId().equals(PamirsSession.getUserId())).collect(Collectors.toList());
        Map<Long, WorkflowUserTask> userTaskMap = userTasks.stream().collect(Collectors.toMap(WorkflowUserTask::getNodeDataBizId, v -> v, (a, b) -> a));
        Map<Long, String> nodeNameResult = nodeNameResult(allUserTasks);
        datas.forEach(item -> {
            item.setCanUrge(Boolean.FALSE);
            WorkflowUserTask currenctWorkflowUserTask = userTaskMap.get(item.getId());
            if (currenctWorkflowUserTask != null) {
                item.setWorkflowUserTaskId(currenctWorkflowUserTask.getId());
                item.setCurrentFlowNode(currenctWorkflowUserTask.getNodeName());
            }
            WorkflowUserTask workflowUserTask = workflowUserTaskMap.get(item.getId());
            if (workflowUserTask != null) {
                item.setInstanceId(workflowUserTask.getInstanceId());
                item.setCurrentFlowNode(nodeNameResult.get(workflowUserTask.getNodeDataBizId()));
                if (workflowUserTask.getInitiatorUid() != null
                        && workflowUserTask.getInitiatorUid().equals(PamirsSession.getUserId())) {
                    item.setCanUrge(Boolean.TRUE);
                }
            }
            if (ApprovalStatusEnum.APPROVED.equals(item.getApprovalStatus())) {
                item.setCurrentFlowNode("审批通过");
            } else if (ApprovalStatusEnum.REJECTED.equals(item.getApprovalStatus())) {
                item.setCurrentFlowNode("审批拒绝");
            }
        });
    }
    private Map<Long, String> nodeNameResult(List<WorkflowUserTask> allUserTasks) {
        // 分组逻辑:按 department 分组,提取 name 并去重拼接
        Map<Long, String> result = new HashMap<>();
        for (WorkflowUserTask userTask : allUserTasks) {
            Long nodeDataBizId = userTask.getNodeDataBizId();
            String nodeName = userTask.getNodeName();

            // 过滤掉 null 和空字符串的 name
            if (nodeName == null || nodeName.trim().isEmpty()) {
                continue;
            }

            // 初始化分组 Set
            result.putIfAbsent(nodeDataBizId, "");

            // 使用 LinkedHashSet 去重并保留顺序
            Set<String> nodeNamesSet = new LinkedHashSet<>();
            if (!result.get(nodeDataBizId).isEmpty()) {
                Collections.addAll(nodeNamesSet, result.get(nodeDataBizId).split(","));
            }
            nodeNamesSet.add(nodeName);

            // 更新结果
            result.put(nodeDataBizId, String.join(",", nodeNamesSet));
        }

        return result;
    }
}

五、效果图

工作流:通过业务数据操作工作流程(催办、撤销等)

Oinone社区 作者:yexiu原创文章,如若转载,请注明出处:https://doc.oinone.top/dai-ma-shi-jian/21291.html

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

(0)
yexiu的头像yexiu数式员工
上一篇 2025年6月24日 pm7:50
下一篇 2025年7月8日 pm3:21

相关推荐

  • 推送自定义消息

    项目中添加消息依赖 pro.shushi.pamirs.core pamirs-message-api 调用pro.shushi.pamirs.message.engine.message.MessageSender#sendSystemMail发送系统消息示例: @Action(displayName = "发送消息") public Student sendMessage(Student data){ MessageSender mailSender = (MessageSender) MessageEngine.get(MessageEngineTypeEnum.MAIL_SEND).get(null); String content = "发送自定义消息"; String subject = null; List<Long> userIds = new ArrayList<>(); userIds.add(PamirsSession.getUserId()); PamirsMessage message = new PamirsMessage() .setName(subject) .setSubject(subject) .setBody(content) .setMessageType(MessageTypeEnum.NOTIFICATION); List<PamirsMessage> messages = new ArrayList<>(); messages.add(message); SystemMessage systemMessage = new SystemMessage(); systemMessage.setPartners(userIds.stream().map(i -> (PamirsUser) new PamirsUser().setId(i)).collect(Collectors.toList())) .setType(MessageGroupTypeEnum.SYSTEM_MAIL) .setMessages(messages); mailSender.sendSystemMail(systemMessage); return data; }

    2024年8月19日
    1.3K00
  • 如何删除系统权限中默认的首页节点

    场景: 并没有设置过首页的配置,为什么在系统权限这里的配置菜单中却有首页的配置。而且显示当前资源未完成初始化设置,无法配置。这个文章将帮助你删除这个节点。 注意:如果添加了以下代码,后续如果需要使用首页的配置,则需要删除该代码。 扩展权限加载节点: 遍历权限加载的节点,找到需要删除的模块首页节点。删除节点。 @Component @Order(88) @SPI.Service public class MyTestNodeLoadExtend implements PermissionNodeLoadExtendApi { @Override public List<PermissionNode> buildRootPermissions(PermissionLoadContext loadContext, List<PermissionNode> nodes) { //删除 TopModule.MODULE_MODULE 的首页节点。 String homepage = TranslateUtils.translateValues(PermissionNodeLoaderConstants.HOMEPAGE_DISPLAY_VALUE); for (PermissionNode node : nodes) { //如果需要删除多个模块的首页,在这里多加一个逻辑与条件即可。 if (!(node instanceof ModulePermissionNode) || !TopModule.MODULE_MODULE.equals(((ModulePermissionNode) node).getModule())) { continue; } List<PermissionNode> permissionNodes = node.getNodes(); Iterator<PermissionNode> iterator = permissionNodes.iterator(); while (iterator.hasNext()) { PermissionNode permissionNode = iterator.next(); if (ResourcePermissionSubtypeEnum.HOMEPAGE.equals(permissionNode.getNodeType()) && homepage.equals(permissionNode.getDisplayValue())) { iterator.remove(); //如果是删除多个模块首页,这里的return改为break; return nodes; } } } return nodes; } } 看效果:首页节点成功删除。

    2024年12月31日
    1.4K00
  • 同一行操作跳转到不同的视图(动态表单)

    背景 实际项目中,存在这样的场景:同一列表中的数据是泛化的数据集合,即数据来源于不同的模型;行操作需要根据来源去向不同的目标页。 如下图,「提报」操作需根据「报表类型」去向不同的表单。 并支持目标弹窗标题和弹框大小的配置。 解决思路 每行记录需要跳转到不同的模型不同视图,增加一个配置页面用于维护源模型和目标模型的调整动作关系; 返回数据的时候,同时返回自定义的动作。 前端自定义实现如上面图例中的「填报」,从返回数据中获取ViewAction并做对应的跳转。 具体步骤 [后端] 建立模型和视图的关系设置的模型 1、创建 模型和视图的关系设置的模型,用于配置列表模型和各记录即目标模型的视图关系 import pro.shushi.oinone.examples.simple.api.proxy.system.SimpleModel; import pro.shushi.oinone.examples.simple.api.proxy.system.SimpleModule; import pro.shushi.pamirs.boot.base.enmu.ActionTargetEnum; import pro.shushi.pamirs.boot.base.model.View; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.IdModel; import pro.shushi.pamirs.meta.enmu.ViewTypeEnum; /** * 模型和视图的关系设置 * ModelRelViewSetting */ @Model.model(ModelRelViewSetting.MODEL_MODEL) @Model(displayName = "模型和视图的关系设置", summary = "模型和视图的关系设置") @Model.Advanced(unique = {"oModel,model,target,viewType,viewName"}) public class ModelRelViewSetting extends IdModel { public static final String MODEL_MODEL = "examples.custom.ModelRelViewSetting"; @Field.many2one @Field(displayName = "模块") @Field.Relation(relationFields = {"module"}, referenceFields = {"module"}) private SimpleModule moduleDef; @Field.String @Field(displayName = "模块编码", invisible = true) private String module; @Field.many2one @Field(displayName = "源模型") @Field.Relation(relationFields = {"oModel"}, referenceFields = {"model"}) private SimpleModel originModel; @Field.String @Field(displayName = "源模型编码", invisible = true) private String oModel; @Field.many2one @Field(displayName = "目标模型") @Field.Relation(relationFields = {"model"}, referenceFields = {"model"}) private SimpleModel targetModel; @Field.String @Field(displayName = "目标模型编码", invisible = true) private String model; @Field.Enum @Field(displayName = "视图类型") private ViewTypeEnum viewType; @Field.Enum @Field(displayName = "打开方式", required = true) private ActionTargetEnum target; @Field.String @Field(displayName = "动作名称", invisible = true) private String name; @Field.many2one @Field.Relation(relationFields = {"model", "viewName"}, referenceFields = {"model", "name"}, domain = "systemSource=='UI'") @Field(displayName = "绑定页面", summary = "绑定页面") private View view; @Field.String @Field(displayName = "视图/页面", invisible…

    2025年2月19日
    1.0K00
  • 如何给角色增加菜单权限

    对接第三方的权限时,第三方传过来菜单项,需要拿着这些菜单在平台这边进行授权,可以使用代码的方式给指定菜单创建权限代码示例: public class demo { @Autowired private PermissionNodeLoader permissionNodeLoader; @Autowired private AuthRbacRolePermissionServiceImpl authRbacRolePermissionService; public void roleAuthorization() { ArrayList<Menu> menus = new ArrayList<>(); menus.add(new Menu().queryOneByWrapper(Pops.<Menu>lambdaQuery() .from(Menu.MODEL_MODEL) .eq(Menu::getName, "uiMenu90dd10ae7cc4459bacd2845754b658a8") .eq(Menu::getModule, TopModule.MODULE_MODULE))); menus.add(new Menu().queryOneByWrapper(Pops.<Menu>lambdaQuery() .from(Menu.MODEL_MODEL) .eq(Menu::getName, "TopMenus_shoppMenu_Shop3Menu_ShopSayHello52eMenu") .eq(Menu::getModule, TopModule.MODULE_MODULE))); //加载指定角色的全部资源权限项 ResourcePermissionNodeLoader loader = permissionNodeLoader.getManagementLoader(); List<PermissionNode> nodes = loader.buildRootPermissions(); List<AuthRbacResourcePermissionItem> authRbacRolePermissionProxies = new ArrayList<>(); //给指定角色创建权限,如果需要多个角色,可以for循环依次执行authRbacRolePermissionService.update(authRbacRolePermissionProxy) AuthRole authRole = new AuthRole().queryOneByWrapper(Pops.<AuthRole>lambdaQuery() .from(AuthRole.MODEL_MODEL) .eq(AuthRole::getCode, "R003") .eq(AuthRole::getName, "R003")); AuthRbacRolePermissionProxy authRbacRolePermissionProxy = new AuthRbacRolePermissionProxy(); AuthRole.transfer(authRole, authRbacRolePermissionProxy); for (PermissionNode node : nodes) { traverse(node, authRbacRolePermissionProxies, menus); } authRbacRolePermissionProxy.setResourcePermissions(authRbacRolePermissionProxies); authRbacRolePermissionService.update(authRbacRolePermissionProxy); } private void traverse(PermissionNode node, List<AuthRbacResourcePermissionItem> authRbacRolePermissionProxies, ArrayList<Menu> menus) { if (node == null) { return; } //按照指定菜单进行过滤,如果不是指定菜单,则设置菜单项不可访问,如果是指定菜单,则设置可访问 Set<Long> menuIds = new HashSet<>(); for (Menu menu : menus) { menuIds.add(menu.getId()); } if (node instanceof MenuPermissionNode) { AuthRbacResourcePermissionItem item = new AuthRbacResourcePermissionItem(); if (menuIds.contains(Long.parseLong(node.getId()))) { item.setCanAccess(Boolean.TRUE); } else { item.setCanAccess(Boolean.FALSE); } item.setCanManagement(node.getCanManagement()); item.setPath(node.getPath()); item.setSubtype(node.getNodeType()); item.setType(AuthEnumerationHelper.getResourceType(node.getNodeType())); item.setDisplayName(node.getDisplayValue()); item.setResourceId(node.getResourceId()); authRbacRolePermissionProxies.add(item); } List<PermissionNode> childNodes = node.getNodes(); if (CollectionUtils.isNotEmpty(childNodes)) { for (PermissionNode child : childNodes) { traverse(child, authRbacRolePermissionProxies, menus); } } } } 执行看效果

    2024年11月14日
    1.0K00
  • 部分模型不动态修改表结构(由单独DDL处理)

    需求描述 实际项目中, 存在部分模型不动态修改表结构,由单独DDL脚本处理,常见的场景有: 已存在库和表中使用Oinone进行功能开发,此时对于已经存在的表对应的模型不允许改表结构 其他情况不希望动态改变表结构的情况 实现步骤 新建NODDL的基础模型 模型公共字段 公共字段说明:使用Oinone进行开发时,业务模型需继承基础IdModel(或者由IdModel衍生出的子类),这些基础模型有createDate(创建时间)、writeDate(更新时间)、createUid(创建人ID)和writeUid(更新人ID)等公共字段;实际表中公共字段可能与Oinone有所不同。 实现方式 方式1:公共属性字段用平台提供的createDate、writeDate、createUid和writeUid,通过指定column与表中的实际字段对应.【推荐】该方式,公共字段的处理可以继续使用平台的默认赋值处理方式; 方式2:继承平台的时候,把公共字段排除掉(配置unInheritedFields),然后自行加通用字段:排除字段:@Model.Advanced(type= ModelTypeEnum.ABSTRACT, ordering = "createAt DESC, id DESC", unInheritedFields = {"createUid","writeUid","createDate","writeDate"})【不推荐】该方式,公共字段的赋值逻辑需要自行处理,略显复杂; 实现方式举例 下面的示例以方式1举例;假设表的基础字段分别是:createAt、updateAt、createId和updateId 与平台的不同. 不自动DDL的抽象模型示例 import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.IdModel; import pro.shushi.pamirs.meta.enmu.FieldStrategyEnum; import pro.shushi.pamirs.meta.enmu.ModelTypeEnum; import java.util.Date; /** * 假设表的基础字段分别是:createAt、updateAt、createId和updateId 与平台的不同 */ @Model.model(BaseNoDdlModel.MODEL_MODEL) @Model(displayName = "不自动DDL的抽象模型") @Model.Advanced(type= ModelTypeEnum.ABSTRACT, ordering = "createAt DESC, id DESC") public abstract class BaseNoDdlModel extends IdModel { public static final String MODEL_MODEL = "hr.std.BaseNoDdlModel"; // 如果原表的主键的列名不是ID的情况,这里可以定义column指定ID属性对应的列名 /** @Field.PrimaryKey @Field(displayName = "主键ID") @Field.Advanced(column = "XLH") private Long id; **/ // 下面这几个字段按实际项目中的情况来增加,包括字段名 @Field.Advanced(columnDefinition = "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP", column = "createAt", insertStrategy = FieldStrategyEnum.NEVER, updateStrategy = FieldStrategyEnum.NEVER, batchStrategy = FieldStrategyEnum.NEVER) @Field(displayName = "创建时间", priority = 200) private Date createDate; @Field.Advanced(columnDefinition = "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", column = "updateAt", batchStrategy = FieldStrategyEnum.NEVER) @Field(displayName = "更新时间", priority = 210) private Date writeDate; @Field.Advanced(column = "createId") @Field(displayName = "创建人ID", priority = 220, invisible = true) private Long createUid; @Field.Advanced(column = "updateId") @Field(displayName = "更新人ID", priority = 230, invisible = true) private Long writeUid; } 不需动态DDL的业务模型,业务模型继承BaseNoDdlModel。 其他业务模型如果有相同的需求类似的做法 /** * 测试合同表 */ @Model.model(InspectionInfo.MODEL_MODEL) @Model(displayName = "合同", labelFields…

    2025年2月22日
    1.1K00

Leave a Reply

登录后才能评论