3.5.7.8 自定义菜单栏

在业务中,可能会遇到需要对菜单栏的交互或UI做全新设计的需求,这个时候可以自定义菜单栏组件支持。

首先继承平台的CustomMenuWidget 组件,将自己vue文件设置到component处

import { NavMenu, SPI, ViewWidget } from '@kunlun/dependencies';
import Component from './CustomMenu.vue';

@SPI.ClassFactory(
  ViewWidget.Token({
    // 这里的widget跟平台的组件一样,这样才能覆盖平台的组件
    widget: 'nav-menu'
  })
)
export class CustomMenuWidget extends NavMenu {

  public initialize(props) {
    super.initialize(props);
    this.setComponent(Component);
    return this;
  }
}

vue文件中继承平台的props,编写自定义页面代码

export const NavMenuProps = {
  /**
   * 当前模块
   */
  module: {
    type: Object as PropType<IModule | null>
  },
  /**
   * 树结构的菜单
   */
  menus: {
    type: Array as PropType<IResolvedMenu[]>,
    default: () => []
  },
  /**
   * 菜单类型,现在支持垂直、水平、和内嵌模式三种
   */
  mode: {
    type: String as PropType<'vertical' | 'horizontal' | 'inline'>,
    default: 'inline'
  },
  /**
   * 菜单栏是否折叠收起
   */
  collapsed: {
    type: Boolean,
    default: false
  },
  /**
   * 当前展开的 SubMenu 菜单项 key 数组
   */
  openKeys: {
    type: Array as PropType<string[]>,
    default: () => []
  },
  /**
   * 当前选中的菜单项 key 数组
   */
  selectKeys: {
    type: Array as PropType<string[]>,
    default: () => []
  },
  /**
   * 菜单搜索下拉选中菜单项
   */
  selectMenuBySearch: {
    type: Function as PropType<(menuName: String) => void>
  },
  /**
   * 选中菜单项
   */
  selectMenu: {
    type: Function as PropType<(menuName: String) => Promise<void>>
  },
  /**
   * SubMenu 展开/关闭的回调
   */
  openChange: {
    type: Function as PropType<(openKeys: string[]) => void>
  },
  /**
   * 菜单栏折叠的回调
   */
  onChangeCollapsed: {
    type: Function as PropType<(collapsed: boolean) => Promise<void>>
  }
};
<template>
  <div class="k-oinone-menu-wrapper custom-menu">
    <div class="menu-search" v-if="module && mode === 'inline' && !collapsed">
      <a-select
        ref="menuSelectSearch"
        dropdown-class-name="ui-designer-select-global"
        option-filter-prop="label"
        placeholder="搜索菜单"
        :show-search="true"
        @change="innerSearchSelect"
      >
        <a-select-option
          v-for="opt in module.allMenus.filter((_f) => _f.viewAction)"
          :key="opt.name"
          :value="opt.name"
          :label="opt.displayName"
        >
          {{ opt.displayName }}
        </a-select-option>
        <template #suffixIcon>
          <oio-icon icon="oinone-sousuo" size="14px" color="var(--oio-menu-default-icon-color)" />
        </template>
      </a-select>
    </div>
    <div class="menu-area oio-scrollbar">
      <div class="menu-content" :class="collapsed && 'collapsed'">
        <template v-for="item in menus" :key="item.key">
          <template v-if="!item.children || !item.children.length">
            <div :key="item.key" :title="item.title" class="root-menu" @click="selectMenu(item.key)">
              {{ item.title }}
            </div>
          </template>
          <template v-else>
            <div class="menu-group">
              <div class="root-menu" :title="item.title">{{ item.title }}</div>
              <div class="sub-menus">
                <template v-for="subItem in item.children" :key="subItem.key">
                  <div class="sub-menu" :title="subItem.title" @click="selectMenu(subItem.key)">
                    {{ subItem.title }}
                  </div>
                </template>
              </div>
            </div>
          </template>
        </template>
      </div>
    </div>

    <div class="menu-footer" :class="collapsed && 'collapsed'">
      <div class="menu-toggle-collapsed" @click="onChangeCollapsed(!collapsed)">
        <span class="collapsed-icon">
          <oio-icon
            :icon="collapsed ? 'oinone-menu-caidanzhankai' : 'oinone-menu-caidanshouqi'"
            size="16px"
            color="var(--oio-menu-default-icon-color)"
          />
        </span>
        <span v-show="!collapsed" class="collapsed-text">点击收起菜单</span>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, nextTick } from 'vue';
import { OioIcon, NavMenuProps } from '@kunlun/dependencies';

export default defineComponent({
  props: {
    ...NavMenuProps
  },
  components: {
    OioIcon
  },
  setup(props) {
    const DEFAULT_MENU_ICON = 'oinone-menu-caidanmoren';

    onMounted(async () => {
      await nextTick();
      props.onChangeCollapsed?.(false);
    });

    const menuSelectSearch = ref();
    const innerSearchSelect = (menuName) => {
      props.selectMenuBySearch?.(menuName);
      menuSelectSearch.value?.blur?.();
    };
    return {
      DEFAULT_MENU_ICON,
      menuSelectSearch,
      innerSearchSelect
    };
  }
});
</script>
<style lang="scss">
.custom-menu {
  .root-menu,
  .sub-menu {
    text-indent: 12px;
    cursor: pointer;
    &:hover {
      background: rgba(var(--oio-primary-color-rgb), 0.1);
    }
  }
  .sub-menus {
    padding-left: 20px;
  }
}
</style>

文件目录结构如下图

image.png

最后再到运行路径中导入该组件

这里以启动工程的 main.ts 举例,如果运行时未看到该组件的效果,请检查是否正确导入到运行时的路径中

image.png

以上自定义菜单栏的页面效果如下(该组件仅供演示,所以未实现3级菜单,可自行用子组件实现)

image.png

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9271.html

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

(0)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am9:07
下一篇 2024年5月23日 am9:09

相关推荐

  • 1.5 Oinone与行业对比

    随着企业数字化转型的推进,软件公司获得了许多机会。尽管竞争日趋激烈,但由于需求旺盛,各种模式仍在不断涌现。因此,当前市场上存在各种各样的数字化转型解决方案,围绕企业的各个方面展开。每种解决方案都有其优点和缺点。本文将从定位、技术和产品等方面简单比较,帮助您从不同的视角了解Oinone的差异。 1.4.1 整体视角对比 一、与对标公司Odoo的对比 Odoo Oinone 定位 一站式全业务链管理平台:赋能企业信息化升级 一站式低代码商业支撑平台:赋能企业数字化升级 需求变化 关注单一企业的管理、流程、效率的提升 关注企业价值链的网络竞争,围绕外部协同、运营、数据、商业展开 技术更替 关注稳定、安全、功能丰富度 除了稳定、安全、功能丰富度以外,更强调需求响应速度、用户体验、系统承载极限与弹性扩展、智能化 表1-1 Oinone与对标公司Odoo的对比 二、与国内低代码或无代码公司对比 低代码或无代码公司 Oinone 定位 低代码开发工具:提供各类系统模版,基于模版快速搭建和个性化配置。但系统模版无法再升级 平台型SaaS:提供各类系统产品,产品安装后客户可以根据需求进行个性化调整,同时产品永远在线可升级 场景差异 只能支持企业内部人员使用,以完成部门级边缘系统为主,一般多为没有专业软件厂商支撑和强临时性特性 从内外部协同的商业场景出发,关注企业核心业务场景,适应【企业业务在线化后,所有的业务变化与创新都需要通过系统来触达上下游】的时代背景,以敏捷响应业务的变化与创新为目标 技术代差 单表支撑100万数据已是业内天花板 支撑单模型数据过亿,无单点瓶颈。封装互联网架构并且做到单体与分布式的灵活部署,为不同大小公司提供不同技术支撑 表1-2 Oinone与国内低代码/无代码公司对比 1.4.2 从技术角度对比 我们不会与其他无代码平台进行比较,因为它们不能解决业务复杂性的问题。相反,我们将重点介绍三种不同的低代码平台模式(如下图1-8所示)。 第一种模式是最基础的低代码平台,也被称为代码生成器。它通过预定义应用程序模板和必要的配置生成代码,简化了工程搭建并提供了一些基础逻辑。虽然在信息化时代内部流程标准化方面较为适合,但在数字化时代外部协同业务在线的情况下就不那么合适了。因为这种模式不能减少研发难度和提高效率,也无法体现敏捷迭代快速创新的优势。 第二种模式是经典的低代码平台,以元数据为基础,以模型为驱动。当无法满足需要时,通过特定方式将代码以插件的形式注入平台,作为低代码平台的内置逻辑,供设计器使用。它的优点在于降低了研发门槛,当无法满足需求时才需要编写代码。它可以实现企业内部的复杂流程和复杂逻辑,但其性能和工程管理存在局限性。性能问题使其不适合处理互联网化的在线业务,而工程管理问题则使其不适合处理快速变化的业务。这也是许多研发人员反对低代码的核心原因之一,因为研发人员变成了辅助角色,而软件工程是一门需要技术能力的学科,让没有技术能力的人主导是违反常理的。对于软件产品公司来说,产品需要迭代规划,需要多人协作,需要工程化管理。 第三种模式是oinone提出的基于互联网架构的低代码平台,它采用低无一体的设计。首先,oinone屏蔽了互联网架构带来的复杂性。其次,同样以元数据为基础,以模型为驱动,但是元数据的生成方式有两种:一种是使用无代码设计器(与经典低代码相同),另一种是通过代码来描述元数据。通过使用代码来描述元数据,可以无缝地与代码衔接,并在不改变研发习惯的情况下降低门槛、提高效率,并进行工程化管理。 最后总结来说:低无一体不仅仅是指两种模式的结合,还包括两种模式的融合应用方式。具体来说,这种融合应用方式可以分为两种情况: 当开发核心产品时,主要采用低代码开发,无代码设计器作为辅助。这种方式可以提高开发效率和代码质量,同时保证产品的快速迭代和升级。 当需要满足个性化或非产品支持的需求时,主要采用无代码设计器,低代码作为辅助。这种方式可以快速地满足客户需求,并且避免对产品的核心代码产生影响。 简单来说,低代码模式适用于产品的迭代升级,而无代码设计器则适用于满足个性化和非产品支撑的额外需求。低代码和无代码模式在整个软件生命周期中都有各自的价值,在不同场景下可以相互融合,发挥最大的优势。 图1-8 代码生成器、低代码平台与Oinone的优缺点对比 1.4.3 从产品角度对比 产品上的对比,从客户、场景满足度、再次销售三个方面来做简易的对比 一、Oinone vs 数字化软件服务商 客户 满足度 销售 Oinone 一站式商业智能软件,更高性价比、用户体验客户范围:5000万~5亿、5亿~100亿、标杆:100亿~1000亿、1000亿以上 满足企业核心业务需求,并联合伙伴一起满足企业所有需求,无需集成提供统一工作台、数据接口、底层协议,无论基于Oinone的开源框架还是增加其他应用都有很好的扩展性 支持OP+SaaS两种模式,收费方式不同:OP按买断方式进行,SaaS按效果付费跟账号数无关新的模块进行二次销售 数字化软件服务商 针对成熟的大型企业需投入巨大资源和成本客户范围:100亿~1000亿、1000亿以上 满足企业部分需求,无法输出技术标准,无法解决多供应商一起开发的问题,只能通过集成实现对接 OP模式进行销售,通过设置权限来进行来实现二次销售或无法进行二次销售 表1-3 Oinone vs 数字化软件服务商 二、Oinone vs 低代码或无代码行业 客户 满足度 销售 Oinone 一站式商业智能软件客户范围:5000万~5亿、5亿~100亿、标杆:100亿~1000亿、1000亿以上 从外部商业场景出发,强业务场景驱动,符合企业从信息化管理到业务创新的数字化转变的趋势。提供统一工作台、数据接口、底层协议,无论基于oinone的开源框架还是增加其他应用都有很好的扩展性 支持OP+SaaS两种模式,收费方式不同:OP按买断方式进行,SaaS按效果付费跟账号数无关新的模块进行二次销售 低代码或无代码公司 针对小微企业内部信息化管理诉求,以表单流程为主客户范围:5亿以下 满足企业部门级信息化的适应性需求,无法满足企业核心业务管理与业务创新诉求 按应用模块进行收费,新的模块进行二次销售 表1-4 Oinone vs 低代码或无代码行业 三、Oinone vs 国外对标公司Odoo 客户 满足度 销售 Oinone 一站式商业智能软件客户范围:5000万~5亿、5亿~100亿、标杆:100亿~1000亿、1000亿以上 从外部商业场景出发,强业务场景驱动,符合企业从信息化管理到业务创新的数字化转变的趋势。基线产品覆盖:采购、营销、服务、销售、交易等企业商业领域。主要涉及行业:零售品牌。其他领域或行业靠合作伙伴共建方式进行 支持OP+SaaS两种模式,收费方式不同:OP按买断方式进行,SaaS按效果付费跟账号数无关新的模块进行二次销售 Odoo 一站式企业管理软件客户范围:5000万~5亿、5亿~100亿、标杆:100亿~1000亿、1000亿以上 从企业内部管理需求出发,逐渐拥有互联网相关应用组件,但还是属于强内部管理、弱外部场景。基线产品覆盖:业务财务一体化、人财务、进销存。主要涉及行业:建造业。其他领域或行业靠合作伙伴共建方式进行 支持OP+SaaS两种模式,收费方式相同:按用户数+应用模块进行收费新的模块进行二次销售 表1-5 Oinone vs 国外对标公司Odoo

    2024年5月23日
    1.4K20
  • 2.1 数字化时代软件业的另一个本质变化

    随着企业从信息化向数字化转变,软件公司提供的产品也由传统的企业管理软件向企业商业支撑软件发展。这一变化带来了许多技术上的挑战和机遇。在之前的章节中,我们提到企业的视角已经从内部管理转向业务在线和生态在线协同,这也带来了一系列新的需求。但是,我们常常会忽视这一变化所带来的对系统要求的变化。在本章中,我们将探讨这些技术上的变化,以及这些变化所带来的机遇和挑战。 图2-1 从信息化到数字化软件本质变化 在信息化时代,企业的业务围绕着内部管理效率展开,借鉴国外优秀的管理经验,企业将其管理流程固化下来,典型的例子是ERP项目。这类项目上线后往往长期稳定,不轻易更改,因此信息化时代软件的技术流派侧重于通过模型对业务进行全面支持。例如,SAP具有丰富的配置能力,将已有企业管理思想抽象到极致。其功能基本上可以通过配置来实现,因此其模型设计特别复杂。但是,我们也应该清楚地了解到,配置是面向已知问题的。在数字化时代,创新和业务迭代速度非常快,这种方法可能就不太适合了。我们知道,模型抽象是在设计时具有前瞻性的,一旦不适合,修改起来就会异常困难。 随着数字化时代的到来,企业主的关注点已经从单一企业内部管理转变为了围绕企业上下游价值链的协同展开。这种变化给企业信息化系统提出了更高的要求,例如业务需求的响应速度、系统性能和用户体验等方面。现在,企业对软件不仅是管理需求的承载,更是业务在线化的承载。传统的重模型设计软件模式已经不再适用,因为业务本身不断创新和变化。因此,数字化时代需要新的软件技术流派,这种流派必须是轻模型加上低代码技术的结合体。通过模型抽象80%的通用场景,剩余的20%个性化需求可以通过技术手段来完成。这样的设计可以让每家企业的研发人员轻松理解模型,而不像ERP模型那样异常复杂,无法进行修改。此外,配合低代码技术可以快速研发和上线。如果说配置化是面向已知问题的,那么低代码就是面向未知问题设计的。虽然低代码的概念可以追溯到上个世纪80年代,当时是为了满足企业内部部门之间有协同需求,但又没有专业软件支撑,定制化开发又不划算的辅助场景。但现在它的核心原因是企业数字化的核心场景不稳定,变化很快,每家企业都有强烈的个性化需求。因此,低代码成为解决这些问题的核心手段,数字化时代的低代码需要具备处理复杂场景的能力,而不仅仅是围绕着内部管理展开。 企业在数字化转型的过程中需要考虑到不仅是成熟的全链路业务解决方案,还要应对数字化场景的快速变化和持续创新的需求。为此,Oinone打造了一站式低代码商业支撑平台,从业务与技术两个维度来帮助企业建立开放、链接、安全的数字化平台。这将在水平和垂直两个维度上全面推动企业数字化转型。 另外,低代码的另一个好处是完成了软件本身的数字化建设。通过基于元数据设计,元数据成为软件中数据、逻辑和交互的数据,软件结合AI可以有更多的创造可能。想象一下,AI了解软件的元数据后可以自我运作,人在极少情况下才需要参与,人机交互也会发生大的改变。未来的软件交互不再需要研发提前预设,而是能够实现用户所需即所呈现的效果。作为一家帮助企业进行数字化转型的软件公司,请问您的数字化转型是否已经完成呢?

    2024年5月23日
    1.1K00
  • 4.1.13 Action之校验

    在3.5.3【Action的类型】一文中有涉及到“ServerAction之校验”部分,本文介绍一个特殊的写法,当内置函数和表达式不够用的时候,怎么扩展。还是拿PetShopProxyAction举例,修改如下: package pro.shushi.pamirs.demo.core.action; ……引依赖类 @Model.model(PetShopProxy.MODEL_MODEL) @Component public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> { ……其他代码 // @Validation(ruleWithTips = { // @Validation.Rule(value = "!IS_BLANK(data.code)", error = "编码为必填项"), // @Validation.Rule(value = "LEN(data.shopName) < 128", error = "名称过长,不能超过128位"), // }) @Validation(check = "checkName") @Action(displayName = "启用") @Action.Advanced(rule="activeRecord.code !== undefined && !IS_BLANK(activeRecord.code)") public PetShopProxy dataStatusEnable(PetShopProxy data){ data = super.dataStatusEnable(data); data.updateById(); return data; } @Function public Boolean checkName(PetShopProxy data) { String field = "name"; String name = data.getShopName(); boolean success = true; if (StringUtils.isBlank(name)) { PamirsSession.getMessageHub() .msg(Message.init() .setLevel(InformationLevelEnum.ERROR) .setField(field) .setMessage("名称为必填项")); success = false; } if (name.length() > 128) { PamirsSession.getMessageHub() .msg(Message.init() .setLevel(InformationLevelEnum.ERROR) .setField(field) .setMessage("名称过长,不能超过128位")); success = false; } return success; } ……其他代码 } 图4-1-13-1 PetShopProxyAction扩展配置 注: check属性指定了校验函数名称,命名空间必须与服务器动作一致。 校验函数的入参必须与服务器动作一致 使用PamirsSession#getMessageHub方法可通知前端错误的属性及需要展示的提示信息,允许多个。

  • 3.3.10 字段类型之关系描述的特殊场景

    在3.3.9【字段类型之关系与引用】一文中已经描述了各种关系字段的常规写法,还有一些特殊场景如:关系映射中存在常量,或者M2M中间表是大于两个字段构成。 举例说明关系字段-高级用法 场景描述 PetTalent模型增加talentType字段,PetItem与PetTalent的多对多关系增加talentType(达人类型),PetItemRelPetTalent 中间表维护petItemId、petTalentId以及talentType,PetDogItem和PetCatItem分别重写petTalents 字段,关系中增加常量描述。示意图如下 实际操作步骤: Step1 新增 TalentTypeEnum package pro.shushi.pamirs.demo.api.enumeration; import pro.shushi.pamirs.meta.annotation.Dict; import pro.shushi.pamirs.meta.common.enmu.BaseEnum; @Dict(dictionary = TalentTypeEnum.DICTIONARY,displayName = "达人类型") public class TalentTypeEnum extends BaseEnum<TalentTypeEnum,Integer> { public static final String DICTIONARY ="demo.TalentTypeEnum"; public final static TalentTypeEnum DOG =create("DOG",1,"狗达人","狗达人"); public final static TalentTypeEnum CAT =create("CAT",2,"猫达人","猫达人"); } Step2 PetTalent模型增加talentType字段 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.demo.api.enumeration.TalentTypeEnum; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; @Model.model(PetTalent.MODEL_MODEL) @Model(displayName = "宠物达人",summary="宠物达人",labelFields ={"name"}) public class PetTalent extends AbstractDemoIdModel{ public static final String MODEL_MODEL="demo.PetTalent"; @Field(displayName = "达人") private String name; @Field(displayName = "达人类型") private TalentTypeEnum talentType; } Step3 修改PetItem的petTalents字段,在关系描述中增加talentType(达人类型) @Field.many2many(relationFields = {"petItemId"},referenceFields = {"petTalentId","talentType"},through = "PetItemRelPetTalent") @Field.Relation(relationFields = {"id"}, referenceFields = {"id","talentType"}) @Field(displayName = "推荐达人",summary = "推荐该商品的达人们") private List<PetTalent> petTalents; Step4 PetDogItem增加petTalents字段,重写父类PetItem的关系描述 talentType配置为常量,填入枚举的值 增加domain描述用户页面选择的时候自动过滤出特定类型的达人,RSQL用枚举的name @Field.many2many(relationFields = {"petItemId"},referenceFields = {"petTalentId","talentType"},through = "PetItemRelPetTalent") @Field.Relation(relationFields = {"id"}, referenceFields = {"id","talentType"}) @Field(displayName = "推荐达人",summary = "推荐该商品的达人们") private List<PetTalent> petTalents; Step5 PetCatItem增加petTalents字段,重写父类PetItem的关系描述 talentType配置为常量,填入枚举的值 增加domain描述用户页面选择的时候自动过滤出特定类型的达人,RSQL用枚举的name @Field(displayName = "推荐达人") @Field.many2many( through = "PetItemRelPetTalent", relationFields = {"petItemId"}, referenceFields = {"petTalentId","talentType"} ) @Field.Relation(relationFields = {"id"}, referenceFields = {"id", "#2#"}, domain = " talentType == CAT") private List<PetTalent> petTalents; Step6 清除中间表demo_core_pet_item_rel_pet_talent的数据记录 清除PetItem与PetTalent的多对多中间表demo_core_pet_item_rel_pet_talent的数据记录 Step7 重启看效果 修改达人记录,选择不同达人类型 PetItem、PetCatItem、PetDogItem不同的交互页面

    2024年5月23日
    1.4K00
  • 4.1.23 框架之信息传递

    在4.1.13【Action之校验】、3.4.1【构建第一个Function】等文章中,都用到PamirsSession.getMessageHub()来设置返回消息,基本上都是在传递后端逻辑判断的异常信息,而且在系统报错时也会通过它来返回错误信息,前端接收到错误信息则会以提示框的方式进行错误提示。其实后端除了可以返回错误信息以外,还可以返回调试、告警、成功、信息等级别的信息给前端。但是默认情况下前端只提示错误信息,可以通过前端的统一配置放开提示级别,有点类似后端的日志级别。 一、不同信息类型的举例 Step1 新建PetTypeAction 借用PetType模型的表格页做为信息传递的测试入口,为PetType模型新增一个ServerAction,在代码中对信息的所有类型进行模拟 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; } } 图4-1-23-1 为PetType模型新增一个ServerAction Step2 (前端)修改提示级别 在项目初始化时使用CLI构建初始化前端工程,在src/middleware有拦截器的默认实现,修改信息提示的默认级别为【ILevel.SUCCESS】 图4-1-23-2(前端)修改提示级别 const DEFAULT_MESSAGE_LEVEL = ILevel.SUCCESS; 图4-1-23-3(前端)修改提示级别 Step3 重启系统看效果 从页面效果中看到已经不在是只提示错误信息。从协议端看错误级别的信息是在errors下,其他级别的信息是在extensions下。 图4-1-23-4 示例效果 图4-1-23-5 系统提示的返回结果 二、MessageHub的其他说明 是实现上看MessageHub是基于GQL协议,前后端都有配套实现。同时前端还提供了订阅MessageHub的信息功能,以满足前端更多交互要求,前端MessageHub提供的订阅能力使用教程详见4.2.2前端高级特性之【框架之MessageHub】一文。

    2024年5月23日
    79100

Leave a Reply

登录后才能评论