框架之MessageHub(信息提示)

框架之信息概述

后端除了可以返回错误信息以外,还可以返回调试、告警、成功、信息等级别的信息给前端。但是默认情况下前端只提示错误信息,可以通过前端的统一配置放开提示级别,有点类似后端的日志级别。

框架之MessageHub

在oinone平台中,我们怎么做到友好的错误提示呢?接下来介绍我们的MessageHub,它为自定义错误提示提供无限的可能。

何时使用

错误提示是用户体验中特别重要的组成部分,大部分的错误体现在整页级别,字段级别,按钮级别。友好的错误提示应该是怎么样的呢?我们假设他是这样的

  • 与用户操作精密契合
    • 当字段输入异常时,错误展示在错误框底部
    • 按钮触发服务时异常,错误展示在按钮底部
  • 区分不同的类型
    • 错误
    • 成功
    • 警告
    • 提示
    • 调试
  • 简洁易懂的错误信息

不同信息类型的举例

package pro.shushi.pamirs.demo.core.action;

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.demo.api.model.PetCatItem;
import pro.shushi.pamirs.demo.api.model.PetType;
import pro.shushi.pamirs.meta.annotation.Action;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.api.dto.common.Message;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.enmu.ActionContextTypeEnum;
import pro.shushi.pamirs.meta.enmu.InformationLevelEnum;
import pro.shushi.pamirs.meta.enmu.ViewTypeEnum;

@Model.model(PetType.MODEL_MODEL)
@Component
public class PetTypeAction {

    @Action(displayName = "消息",bindingType = ViewTypeEnum.TABLE,contextType = ActionContextTypeEnum.CONTEXT_FREE)
    public PetType message(PetType data){
        PamirsSession.getMessageHub().info("info1");
        PamirsSession.getMessageHub().info("info2");
        PamirsSession.getMessageHub().error("error1");
        PamirsSession.getMessageHub().error("error2");
        PamirsSession.getMessageHub().msg(new Message().msg("success1").setLevel(InformationLevelEnum.SUCCESS));
        PamirsSession.getMessageHub().msg(new Message().msg("success2").setLevel(InformationLevelEnum.SUCCESS));
        PamirsSession.getMessageHub().msg(new Message().msg("debug1").setLevel(InformationLevelEnum.DEBUG));
        PamirsSession.getMessageHub().msg(new Message().msg("debug2").setLevel(InformationLevelEnum.DEBUG));
        PamirsSession.getMessageHub().msg(new Message().msg("warn1").setLevel(InformationLevelEnum.WARN));
        PamirsSession.getMessageHub().msg(new Message().msg("warn2").setLevel(InformationLevelEnum.WARN));
        return data;
    }
}

查询运行返回和效果

1)系统提示的返回结果
框架之MessageHub(信息提示)

2)系统提示示例效果
框架之MessageHub(信息提示)

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

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

(0)
望闲的头像望闲数式管理员
上一篇 2024年5月14日 pm10:04
下一篇 2024年5月15日 pm7:27

相关推荐

  • 如何自定义覆盖内置模块的页面

    1.首先通过sql查询找到我们需要的页面,从其中的template字段复制出原视图的配置 通过模型编码model在base_view查找需要修改的视图 select * from base_view where model='workflow.WorkflowUserTask' and is_deleted = 0; 2.将base_view的template内容复制到java的core工程的resources目录下新建一个xml文件,修改里面的动作名称 <view widget="WorkFlowImplement"> <template slot="actions"> <action name="$$internal_GotoListTableRouter" priority="1" model="workflow.WorkflowUserTask" tag="contextFreeAction"/> <action name="approveStaging" widget="FlowTaskCommonAction" invisible="!(activeRecord.allowStaging)" priority="2" label="新暂存" model="workflow.WorkflowUserTask" displayName="新暂存"/> <action name="workflow_agree" invisible="!(activeRecord.allowAgree && activeRecord.status == &apos;ACTIVE&apos;)" priority="3" label="新同意" model="workflow.WorkflowUserTask" load="fetchDetailReadOnly" displayName="新同意" goBack="true" validateForm="true" loadRootData="true"/> <action name="workflow_rejust" invisible="!(activeRecord.allowReject && activeRecord.status == &apos;ACTIVE&apos;)" priority="4" label="新拒绝" model="workflow.WorkflowUserTask" displayName="新拒绝" goBack="true" loadRootData="true" tag="contextFreeAction"/> <action name="workflow_turnon" invisible="!(activeRecord.taskType == &apos;APPROVE&apos; && activeRecord.allowTransfer && activeRecord.status == &apos;ACTIVE&apos;)" priority="5" label="新转交" model="workflow.WorkflowUserTask" load="fetchDetailReadOnly" displayName="新转交" goBack="true" loadRootData="true" tag="contextFreeAction"/> <action name="workflow_addsign" invisible="!(activeRecord.taskType == &apos;APPROVE&apos; && activeRecord.allowAddSign && activeRecord.status == &apos;ACTIVE&apos;)" priority="6" label="新加签" model="workflow.WorkflowUserTask" load="fetchDetailReadOnly" displayName="新加签" goBack="true" loadRootData="true" tag="contextFreeAction"/> <action name="workflow_write_fallback" invisible="!(activeRecord.taskType == &apos;WRITE&apos; && activeRecord.allowFallback && activeRecord.status == &apos;ACTIVE&apos;)" priority="7" label="新回退" model="workflow.WorkflowUserTask" displayName="新回退" goBack="true" loadRootData="true" tag="contextFreeAction"/> <action name="workflow_sharing" priority="8" label="新分享" model="workflow.WorkflowUserTask" displayName="新分享" goBack="true" loadRootData="true" tag="contextFreeAction"/> </template> <template slot="fields"> <field name="remark" widget="TextArea" invisible="activeRecord.taskType != &apos;APPROVE&apos;" priority="8" model="workflow.WorkflowUserTask" data="remark" displayName="意见备注"/> </template> </view> 3.在生命周期的元数据编辑方法内覆盖视图 package pro.shushi.pamirs.demo.core.init; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import pro.shushi.pamirs.boot.common.api.command.AppLifecycleCommand; import pro.shushi.pamirs.boot.common.extend.MetaDataEditor; import pro.shushi.pamirs.core.common.InitializationUtil; import pro.shushi.pamirs.demo.api.DemoModule; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.api.dto.meta.Meta; import pro.shushi.pamirs.meta.enmu.ViewTypeEnum; import pro.shushi.pamirs.workflow.app.api.model.WorkflowUserTask; import java.util.Map; @Slf4j @Component @Order(Ordered.LOWEST_PRECEDENCE) public class DemoModuleMetaInstall implements MetaDataEditor { @Override public void edit(AppLifecycleCommand command,…

    2024年7月2日
    1.3K00
  • 工作流用户待办过滤站内信

    工作流用户待办过滤站内信 全局过滤 启动工程application.yml中配置: pamirs: workflow: notify: false 个性化过滤 实现pro.shushi.pamirs.workflow.app.api.service.WorkflowMailFilterApi接口 返回true表示需要发送站内信 返回false表示不需要发送站内信 示例: import org.apache.commons.lang3.StringUtils; import pro.shushi.pamirs.message.model.PamirsMessage; import pro.shushi.pamirs.meta.annotation.Fun; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.user.api.model.PamirsUser; import pro.shushi.pamirs.workflow.app.api.model.WorkflowUserTask; import pro.shushi.pamirs.workflow.app.api.service.WorkflowMailFilterApi; /** * MyWorkflowMailFilterImpl * * @author yakir on 2025/02/24 16:28. */ @Fun(WorkflowMailFilterApi.FUN_NAMESPACE) public class MyWorkflowMailFilterImpl implements WorkflowMailFilterApi { @Override @Function public Boolean filter(WorkflowUserTask workflowUserTask, PamirsUser user, PamirsMessage message) { // 按用户待办过滤 workflowUserTask if (10000L == workflowUserTask.getInitiatorUid()){ return true; } // 按用户过滤 user if (1000L == user.getId()){ return true; } // 按站内信消息过滤 message if (StringUtils.contains(message.getBody(), "你好")) { return true; } return false; } }

    2025年2月24日
    88300
  • 【Oracle】后端部署使用Oracle数据库

    Oracle数据库配置 驱动配置 jdbc仓库 https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 Maven配置(11g版本可用) <ojdbc.version>23.2.0.0</ojdbc.version> <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>${ojdbc.version}</version> </dependency> JDBC连接配置 pamirs: datasource: base: type: com.alibaba.druid.pool.DruidDataSource driverClassName: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@//127.0.0.1:1521/orcl username: YOUR_SCHEMA_NAME password: xxxxxx Oracle默认为每个用户创建了一个与当前用户名同名的模式,每个用户应该只使用该模式(DBA用户除外),因此平台使用Oracle时应该通过username处指定与该模式同名的用户名来指定模式。(Oracle多数据源时每一个数据库创建一个用户) 创建用户时用户名应全大写。 连接url配置 官方文档 https://odbc.postgresql.org/docs/config-opt.html url格式 jdbc:oracle:thin:@//ip:端口号/服务名或SID 每一个Oracle进程默认为一个Oracle数据库实例,使用服务名或sid登录该Oralce数据库实例。一个Oracle sid 对应一个数据库实例,而一个服务名可以标识多个数据库实例。远程连接时推荐使用服务名进行连接。可以在安装Oracle的机器上打开SQLPlus,用SYSTEM用户登录上去后使用SELECT SYS_CONTEXT('USERENV', 'INSTANCE_NAME') AS SID FROM DUAL;查询登录使用的sid;也可以使用SELECT VALUE AS SERVICE_NAME FROM V$PARAMETER WHERE NAME = 'service_names';查询登录使用的服务名。 其他连接参数如需配置,可自行查阅相关资料进行调优。 方言配置 pamirs方言配置 pamirs: dialect: ds: base: type: Oracle version: 11.2 major-version: 11g pamirs: type: Oracle version: 11.2 major-version: 11g plus: configuration: jdbc-type-for-null: "NULL" using-model-as-property: true using-statement-handler-dialect: true mapper: batch: useAffectRows global: table-pattern: '${table_30}' column-pattern: '${column_30}' 数据库版本 type version majorVersion 11g – 11.2.0.1.0 Oracle 11.2 11g 12c – 12.2.0.1.0 Oracle 12.2 12c PS:由于方言开发环境为Oracle Database 11g Enterprise Edition Release 11.2.0.1.0版本,其他类似版本(11.2.x)原则上不会出现太大差异,如出现其他版本无法正常支持的,可在文档下方留言。 schedule方言配置 pamirs: event: enabled: true schedule: enabled: true dialect: type: Oracle version: 11.2 major-version: 11g 其他配置 逻辑删除的值配置 pamirs: mapper: global: table-info: logic-delete-value: (CAST(SYSTIMESTAMP AS DATE) – TO_DATE('1970-01-01 08:00:00', 'YYYY-MM-DD HH24:MI:SS')) * 8640000000000 Oracle数据库用户初始化及授权 — 以下命令均使用dba账户执行 — 创建用户 ONE_TEST (用户名需全大写) 密码 123456 CREATE USER ONE_TEST IDENTIFIED BY 123456; — 解锁用户 ALTER USER ONE_TEST ACCOUNT UNLOCK; — 将用户的默认表空间设置为USERS,临时表空间设置为TEMP ALTER USER ONE_TEST DEFAULT TABLESPACE USERS; ALTER USER ONE_TEST TEMPORARY TABLESPACE TEMP; — 可以用以下命令查询某用户的表空间: SELECT…

    2025年7月10日
    31500
  • 自定义审批方式、自定义审批节点名称

    @Model.model(审批模型.MODEL_MODEL) @Component public class 审批模型Action { @Function @Function.Advanced(category = FunctionCategoryEnum.CUSTOM_DESIGNER, displayName = "测试自定义审批类型") public WorkflowSignTypeEnum signType(String json) { // json为业务数据,可用JsonUtils转换 return WorkflowSignTypeEnum.COUNTERSIGN_ONEAGREE_ONEREJUST; } @Function @Function.Advanced(category = FunctionCategoryEnum.CUSTOM_DESIGNER, displayName = "测试自定义审批名称") public String customApprovalName() { return UUID.randomUUID().toString(); } }

    2023年12月5日
    1.3K00
  • 技术精要:数据导出与固化实用指南

    数据被认为是企业发展和决策的重要资产。随着业务的不断发展和数据量的不断增加,企业通常需要将数据从不同的源头导出,并将其固化到产品中,以便进行进一步的分析、处理和利用。数据导出与固化的过程涉及到数据的提取、清洗、整合和存储,是确保数据长期有效性和可用性的关键步骤。 了解数据导出与固化的流程和方法对于企业具有重要意义。通过有效的数据导出和固化,企业可以更好地管理和利用数据资源,提升决策的准确性和效率,实现业务的持续发展和创新。本次讨论将重点探讨数据导出与固化的流程和关键步骤,帮助参与者深入了解如何将数据从导出到产品中,为企业数据管理和应用提供有力支持。 1. 数据导出与固化:将数据从导出到产品中的流程 1.1. pom依赖: <dependency> <groupId>pro.shushi.pamirs.metadata.manager</groupId> <artifactId>pamirs-metadata-manager</artifactId> </dependency> 1.2 将第⼆步下载后的⽂件放⼊项⽬中(注意⽂件放置的位置)。放置⼯程的resources 下⾯。例如: 1.3 项⽬启动过程中,将⽂件中的数据导⼊(通常放在core模型的init包下 ⾯)。⽰例代码: package pro.shushi.pamirs.sys.setting.enmu; import com.google.common.collect.Lists; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import pro.shushi.pamirs.boot.common.api.command.AppLifecycleCom mand; import pro.shushi.pamirs.boot.common.api.init.LifecycleCompleted AllInit; import pro.shushi.pamirs.boot.common.extend.MetaDataEditor; import pro.shushi.pamirs.core.common.InitializationUtil; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.api.dto.meta.Meta; import pro.shushi.pamirs.meta.domain.module.ModuleDefinition; import pro.shushi.pamirs.metadata.manager.core.helper.DesignerIn stallHelper; import pro.shushi.pamirs.metadata.manager.core.helper.WidgetInst allHelper; import java.util.List; import java.util.Map; @Slf4j @Component public class DemoAppMetaInstall implements MetaDataEditor, LifecycleCompletedAllInit { @Autowired private ApplicationContext applicationContext; @Override public void edit(AppLifecycleCommand command, Map<String, Meta> metaMap) { if (!doImport()) { return; } log.info("[设计器业务元数据导⼊]"); InitializationUtil bizInitializationUtil = InitializationUtil.get(metaMap, DemoModule.MODULE_MODULE/ ***改成⾃⼰的Module*/, DemoModule.MODULE_NAME/***改成⾃⼰的 Module*/); DesignerInstallHelper.mateInitialization(bizInitializatio nUtil, "install/meta.json"); log.info("[⾃定义组件元数据导⼊]"); // 写法1: 将组件元数据导⼊到⻚⾯设计器. 只有在安装设计器的 服务中执⾏才有效果 WidgetInstallHelper.mateInitialization(metaMap, "install/widget.json"); // 写法2: 与写法1相同效果 InitializationUtil uiInitializationUtil = InitializationUtil.get(metaMap, "ui_designer", "uiDesigner"); if (uiInitializationUtil != null) { DesignerInstallHelper.mateInitialization(uiInitialization Util, "install/widget.json"); } // 写法3: 业务⼯程和设计器分布式部署,且希望通过业务⼯程导⼊ ⾃定义组件元数据. 业务模块需要依赖⻚⾯设计器模块,然后指定业务模块导 ⼊ DesignerInstallHelper.mateInitialization(bizInitializatio nUtil, "install/widget.json"); } @Override public void process(AppLifecycleCommand command, Map<String, ModuleDefinition> runModuleMap) { if (!doImport()) { return; } log.info("[设计器业务数据导⼊]"); // ⽀持远程调⽤,但是执⾏的⽣命周期必须是 LifecycleCompletedAllInit或之后. 本地如果安装了设计器,则没有要 求 DesignerInstallHelper.bizInitialization("install/ meta.json"); log.info("[⾃定义组件业务数据导⼊]"); // 当开发环境和导⼊环境的⽂件服务不互通时, 可通过指定js和 css的⽂件压缩包,⾃动上传到导⼊环境,并替换导⼊组件数据中的⽂件url // WidgetInstallHelper.bizInitialization("install/ widget.json", "install/widget.zip"); WidgetInstallHelper.bizInitialization("install/ widget.json"); return; } private boolean doImport() { // ⾃定义导⼊判断. 避免⽤于设计的开发环境执⾏导⼊逻辑 String[] envs = applicationContext.getEnvironment().getActiveProfiles(); List<String> envList = Lists.newArrayList(envs); return…

    2024年2月27日
    1.6K00

Leave a Reply

登录后才能评论