Oinone平台可视化调试工具

为方便开发者定位问题,我们提供了可视化的调试工具。
该文档将介绍可视化调试工具的基本使用方法。

概述

调试工具分为两部分内容

  • 页面调试
  • 接口调试

PS:可视化调试工具仅能用于测试当前环境,无法跨环境测试。

页面调试概述

对当前页面的前端运行时上下文做了简单的解析,主要用于解决元数据权限视图等常见问题。

接口调试概述

对任何Oinone平台发起的标准请求,都可以使用该调试工具进行检查。主要用于解决异常堆栈权限SQL执行等相关问题的排查。

表述解释

为了方便表述,以下内容包含的后端模型字段/方法或GQL请求相关信息,其表述规则为:

{ClassSimpleName/GQLNamespace}#{field/method}

例如后端模型字段/方法:(该示例并不在平台代码中,仅作为展示)

public class ModuleDefinition {
    private String module;

    public void queryOne() {
        ...
    }
}

ClassSimpleNameJava类的类名,在上述例子中,ClassSimpleNameModuleDefinition
该Java类下的module字段可以表述为ModuleDefinition#module
该Java类下的queryOne方法可以表述为ModuleDefinition#queryOne

例如:

{
  viewActionQuery {
    load(
      ...
    ) {
      ...
    }
  }
}

GQLNamespace为GQL的首个字段在移除QueryMutation后缀后的结果,在上述例子中,GQLNamespaceviewAction
该GQL请求调用了load方法,可以将该请求简单表述为viewAction#load

PS:通常情况下,Java类名采用大驼峰表述,而GQL采用小驼峰表述。因此可以根据首字母为大写或小写区分其表述的具体内容。

以下所有内容表述均建立在此基础之上。

调试工具使用说明

进入调试工具页面

在需要调试的页面,通过修改浏览器URL的方式进入调试工具页面。如下图所示:

需要调试的页面

如需要调试的页面的URL如下所示:

http://127.0.0.1:9093/page;module=resource;viewType=TABLE;model=resource.ResourceCountryGroup;action=resource%23%E5%9B%BD%E5%AE%B6%E5%88%86%E7%BB%84;scene=resource%23%E5%9B%BD%E5%AE%B6%E5%88%86%E7%BB%84;target=OPEN_WINDOW;menu=%7B%22selectedKeys%22:%5B%22%E5%9B%BD%E5%AE%B6%E5%88%86%E7%BB%84%22%5D,%22openKeys%22:%5B%22%E5%9C%B0%E5%9D%80%E5%BA%93%22,%22%E5%9C%B0%E5%8C%BA%22%5D%7D

将page改为debug后即可进入该页面的调试页面,如下所示:

http://127.0.0.1:9093/debug;module=resource;viewType=TABLE;model=resource.ResourceCountryGroup;action=resource%23%E5%9B%BD%E5%AE%B6%E5%88%86%E7%BB%84;scene=resource%23%E5%9B%BD%E5%AE%B6%E5%88%86%E7%BB%84;target=OPEN_WINDOW;menu=%7B%22selectedKeys%22:%5B%22%E5%9B%BD%E5%AE%B6%E5%88%86%E7%BB%84%22%5D,%22openKeys%22:%5B%22%E5%9C%B0%E5%9D%80%E5%BA%93%22,%22%E5%9C%B0%E5%8C%BA%22%5D%7D

PS:通常我们会将新的URL改好后粘贴到新的浏览器标签页,以保留原页面可以继续查看相关信息。

调试工具页面

进入调试工具页面后,我们可以看到如下图所示的页面:

调试工具页面

调试页面信息概述

  • 下载全部调试数据:包括页面调试接口调试的全部数据。
    • 页面调试数据包含页面参数viewAction#load等页面数据。
    • 接口调试数据仅包含最近一次接口调试相关数据,未发起过请求将没有相关数据。

页面调试信息概述

  • 页面参数:当前URL中所有参数。
    • module:模块名称。ModuleDefinition#name
    • viewType:视图类型。ViewAction#resView#viewType
    • model:当前跳转动作模型编码。ViewAction#model
    • action:当前跳转动作名称。ViewAction#name
  • 页面信息:ViewAction#load接口返回的基础信息。
    • id:当前跳转动作ID。
    • model:同URL参数model
    • name:同URL参数action
    • title:用于浏览器标题以及面包屑显示名称备选项。
    • displayName:用于浏览器标题以及面包屑显示名称备选项。
    • contextType:数据交互上下文类型。
    • target:后端配置路由类型。不同于URL参数中的target。
    • domain:用户可视过滤条件,会根据规则回填至搜索区域
    • filter:用户不可视过滤条件,通过后端DataFilterHook追加至查询条件中。
    • module:跳转动作加载模块编码。
    • moduleName:跳转动作加载模块名称。
    • resModule:目标视图模块编码。
    • resModuleName:目标视图模块名称,用于模块跳转。
    • resViewId:目标视图ID。即当前页面视图ID。
    • resViewModel:目标视图模型编码。即当前页面视图模型编码。
    • resViewName:目标视图名称。即当前页面视图名称。
    • resViewType:目标视图类型。即当前页面视图类型。
    • maskName:后端配置母版名称。
    • layoutName:后端配置布局名称。
  • DSL:当前页面返回的未经处理的全部元数据信息。
  • Layout:当前页面使用的布局数据,当layoutName属性不存在时,该数据来自于前端注册的Layout。
  • Mask:当前页面使用的母版数据。
  • 页面字段:当前页面的全部字段元数据信息。(不包含引用视图)
  • 页面动作:当前页面的全部动作元数据信息。(不包含引用视图)
  • 运行时视图:当前页面的视图元数据信息。
  • 运行时DSL:经过解析的DSL元数据信息。
  • 运行时Layout:经过解析的布局信息。
  • 运行时渲染模板:主视图区域渲染的完整模板,即合并Layout和DSL后的最终结果。
  • 完整上下文:运行时上下文中的全部内容。

接口调试信息概述

  • 接口调试:用于发起一个fetch格式的浏览器请求。
    • 日志级别:根据不同的日志级别返回或多或少的调试信息。(暂未支持)
    • 发起请求:在下方输入框中粘贴fetch格式请求后可以发起真实的接口调用。(生产环境使用时可能产生数据,请确保接口幂等性以及在允许产生测试数据的环境中使用)
    • 重置:还原接口调试页面所有内容。
  • 接口响应结果:完整的接口返回结果。
  • 请求信息:当前请求的基本信息以及性能信息。
    • URL:调试请求的URL。
    • 请求方式:调试请求的Http请求方式。GET/POST
    • 完整请求耗时:从调试请求发起到前端响应并解析完成的时间。
    • 连接耗时:Http请求连接建立的时间。
    • 请求耗时:从调试请求发起到浏览器响应的时间。
    • 响应耗时:从浏览器响应到解析完成的时间。
    • 异常编码:调试请求响应结果中的首个异常信息的错误编码。
    • 异常信息:调试请求响应结果中的首个异常信息的错误信息。
    • 请求头:调试请求的Http请求头信息。
  • GQL#{index}:一个请求中可能包含多个GQL同时发起并调用多个对应的后端函数,index表示其对应的序号。
    • GQL:GQL内容
    • Variables:GQL参数
    • 异常抛出栈:请求出现异常的首个栈,即异常发生地。(无异常不返回)
    • 业务堆栈:不包含Oinone堆栈的调用堆栈信息。
    • 业务与Oinone堆栈:包含Oinone堆栈的调用堆栈信息。
    • 全部堆栈:未经处理的全部堆栈信息。
    • SQL调试:在当前请求链路中用到的所有执行SQL。
    • 函数调用链追踪:在当前请求链路中执行的全部Oinone函数基本信息及耗时。
    • GQL上下文:当前GQL上下文摘要。
    • 会话上下文:当前请求链路到结束的全部PamirsSession上下文信息。
    • 函数信息:当前GQL调用函数信息。
    • 模型信息:当前GQL调用函数对应模型的摘要信息。
    • 环境配置信息:服务端环境配置信息。
    • {GQLNamespace}#{GQLName}:当前执行函数的响应结果。

发起一次接口调试

以下示例均在Chrome浏览器中进行演示,不同浏览器可能存在差异。

使用浏览器查看接口及查看接口异常

如下图所示,通过检查F12打开浏览器控制台,并查看所有接口请求:

无异常接口
无异常接口

有异常接口

有异常接口

PS:一般情况下,所有Oinone请求的Http状态都为200,错误信息在errors数组中进行返回。

在浏览器控制台复制fetch格式请求

复制fetch格式请求

粘贴至接口调试输入框

粘贴至接口调试输入框

点击发起请求即可看到该接口的响应信息

点击发起请求

至此,我们已经完全介绍了现有调试工具的使用及页面展示内容的基本解释。未来我们还会根据需要调试的内容对该调试工具进行补充和完善,尽可能帮助开发者可以高效定位开发过程中遇到的常见问题。

下面,我们将提供几种查看调试信息的简单场景及步骤,帮助开发者可以快速上手并使用调试工具。

调试场景及检查步骤

通常情况下,Oinone平台遇到的问题都可以通过以下调试场景列举的检查步骤轻松定位问题。

当遇到无法通过调试工具定位问题时,可通过下载全部调试数据下载调试数据按钮,将下载的文件发送给Oinone售后服务工程师,并清楚描述遇到的问题,Oinone售后服务工程师会针对该问题提出解决方案或修复方案。

以下调试场景不区分使用页面调试接口调试,需要开发者根据遇到的问题自行判断该使用什么调试工具解决遇到的问题。

SQL示例解释

SQL示例中的表名可能与开发者调试的环境中的表名存在差异,需要开发者根据SQL示例找到对应的数据库及数据表并执行SQL。SQL示例中的参数需要根据开发者所遇到的问题进行调整。

SQL示例中并不包含租户隔离相关字段,请开发者根据运行环境自行补充查询条件。

{URL#model}表示使用URL参数中的model属性值进行替换,其他情况开发者可自行调整。

当页面中的字段/动作未正确显示时

检查当前用户是否具有该字段/动作的权限(超级管理员可跳过此步骤)

使用页面进行检查

步骤1:进入用户模块,查看该用户配置的角色列表,检查是否包含预期角色。
步骤2:进入权限模块,查看该用户所有角色的权限配置,检查是否包含字段的可见权限或动作的访问权限。

使用SQL进行检查

步骤1:根据当前登录用户获取用户ID(请开发者通过当前登录用户信息在user_pamirs_user表中自行查看)
步骤2:查看该用户配置的角色列表,检查是否包含预期角色。

-- 检查当前用户配置的角色列表
select id,name from auth_auth_role where id in (select role_id from auth_user_role_rel where user_id = {userId} and is_deleted = 0) and is_deleted = 0;

步骤3:根据角色列表分别查看字段和动作权限配置相关信息

检查当前跳转动作对应的视图是否为所需视图

步骤1:在页面调试DSL中搜索字段/动作相关信息,看看有没有正确返回。

如正确返回,可根据以下步骤进行检查:

  • 检查元数据是否补充完整。
  • 检查invisible属性是否按预期执行。

如未正确返回,可根据以下SQL示例在数据库中检查相关内容。

-- 检查ViewAction对应的视图是否为预期视图
select id,res_model,res_view_name from base_view_action where model = '{URL#model}' and name = '{URL#action}' and is_deleted = 0;

-- 检查视图的template是否存在字段/动作
select b.id,b.type,b.template from (select res_model,res_view_name from base_view_action where model = ''{URL#model}' and name = ''{URL#action}' and is_deleted = 0) a left join base_view b on a.res_model = b.model and a.res_view_name = b.name;

本文来自投稿,不代表Oinone社区立场,如若转载,请注明出处:https://doc.oinone.top/frontend/6669.html

Like (0)
张博昊's avatar张博昊数式管理员
Previous 2024年4月8日 pm10:15
Next 2024年4月18日 pm8:09

相关推荐

  • 自定义用户中心菜单

    使用扩展点实现用户中心菜单替换 1. 工程中引起pamirs-user-api <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-user-api</artifactId> </dependency> 2. 实现TopBarUserBlockAction的后置扩展 实现HookAfter后置扩展接口 @Hook(model = {TopBarUserBlock.MODEL_MODEL}, fun = {"construct"})添加Hook注解注明是TopBarUserBlock模型的construct函数的后置扩展。 增加用户中心菜单 @Component @Order(1) @SPI.Service public class MyTopBarActionExt implements TopBarActionExtendApi { public void edit(List<TopBarAction> list) { list.add(new TopBarAction("top_demo", "top.Teacher", "uiView9a0caf1d574a42c9847a057a0c4a4ad1", ActionTypeEnum.VIEW, 1) .setDisplayName("商品管理") .setIcon("oinone-gongzuotai") ); } } 实现效果 替换原有的用户中心菜单 替换原有的菜单跳转 @Component public class DemoTopBarUserBlockDataHookAfter implements HookAfter { @Override @Hook(model = {TopBarUserBlock.MODEL_MODEL}, fun = {"construct"}) public Object run(Function function, Object ret) { if (ret == null) { return null; } TopBarUserBlock result = null; if (ret instanceof Object[]) { Object[] rets = (Object[]) ((Object[]) ret); if (rets.length == 1) { result = (TopBarUserBlock) rets[0]; //例:替换用户中心:修改密码菜单 //使用name和model查询出模型的ViewAction替换修改密码ViewAction ViewAction demoViewAction = PamirsSession.getContext().getExtendCache(ActionCacheApi.class).get(Dog.MODEL_MODEL, "changePassword"); //设置菜单的icon Map<String, Object> attributes = Optional.ofNullable(demoViewAction.getAttributes()).orElse(new HashMap<>()); attributes.put("icon", "oinone-xiugaimima"); demoViewAction.setAttributes(attributes); //UserViewAction第0个是修改密码ViewAction,使用自定义的ViewAction就可以实现替换 result.getUserViewAction().set(0, demoViewAction); } } else { result = (TopBarUserBlock) ret; } return result; } } 使用@UxRouteButton方式新增ViewAction,更多新增Action方式详见:Action的类型 @Model.model(Dog.MODEL_MODEL) @Component @UxRouteButton( action = @UxAction(name = "changePassword", displayName = "修改密码"), value = @UxRoute(model = Dog.MODEL_MODEL, openType = ActionTargetEnum.DIALOG)) public class DogAction { } 替换原有的个人设置头像跳转 修改点击头像绑定的跳转逻辑 @Order(10) @Component @SPI.Service public class DemoTopBarUserBlockDataApi implements TopBarUserBlockDataApi { @Override public TopBarUserBlock extendData(TopBarUserBlock data) { //例如增加一个菜单, PamirsDemo.MODEL_MODEL: 模型。 MenuuiMenu31f22466735a4abe8e0544b428ed88ac:viewAction的name。 Action demoViewAction =…

    2024年7月4日
    2.2K00
  • Oinone登录扩展:对接SSO(适应于4.7.8之前的版本)

    适配版本 4.7.8之前的版本 概述 在企业内部,对于已有一套完整的登录系统(SSO)的情况下,通常会要求把所有的系统都对接到SSO中;本文主要讲解用Oinone开发的项目对接SSO的具体实现。 对接步骤 1、项目自定义实现UserCookieLogin,可参考示例说明: pro.shushi.pamirs.user.api.login.UserCookieLoginFree 2、对接SSO示例 对接流程说明: 1)【必须】从请求头Header或者Query中获取到token; 2)【必须】去SSO服务端验证token的有效性; 3)【可选】根据token去服务端获取用户信息;如果token可以直接反解析出用户信息,则该步骤忽略; 4)【可选】根据实际情况用户信息是否进行DB的存储; 5)【必须】验证token有效后,生成Session和Cookie(即token换cookie); 注意超时时间需要 <= SSO服务端token失效时间。 package pro.shushi.pamirs.demo.core.sso; import com.alibaba.fastjson.JSON; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import pro.shushi.pamirs.demo.core.sso.constant.HttpConstant; import pro.shushi.pamirs.demo.core.sso.constant.SSOConstant; import pro.shushi.pamirs.demo.core.sso.constant.SessionUserTypeEnum; import pro.shushi.pamirs.demo.core.sso.model.ApiCommonTransient; import pro.shushi.pamirs.demo.core.sso.utils.AuthenticateUtils; import pro.shushi.pamirs.demo.core.sso.model.PermissionInfoResp; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.api.dto.model.PamirsUserDTO; import pro.shushi.pamirs.meta.api.dto.protocol.PamirsRequestVariables; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.common.exception.PamirsException; import pro.shushi.pamirs.meta.common.spring.BeanDefinitionUtils; import pro.shushi.pamirs.meta.common.util.UUIDUtil; import pro.shushi.pamirs.resource.api.enmu.UserSignUpType; import pro.shushi.pamirs.user.api.cache.UserCache; import pro.shushi.pamirs.user.api.constants.UserConstant; import pro.shushi.pamirs.user.api.enmu.UserExpEnumerate; import pro.shushi.pamirs.user.api.enmu.UserLoginTypeEnum; import pro.shushi.pamirs.user.api.login.IUserLoginChecker; import pro.shushi.pamirs.user.api.login.UserCookieLogin; import pro.shushi.pamirs.user.api.login.UserCookieLoginSimple; import pro.shushi.pamirs.user.api.model.PamirsUser; import pro.shushi.pamirs.user.api.model.tmodel.PamirsUserTransient; import pro.shushi.pamirs.user.api.service.UserService; import pro.shushi.pamirs.user.api.utils.CookieUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.concurrent.TimeUnit; /** * * @author wangxian * * 完全自定义login的过程 * 需要实现登陆部分login 以及拦截部分fetchUserIdByReq * 如果fetchUserIdByReq返回值为null的时候 将会被拦截 */ @Slf4j @Order(0) @Component public class DemoUserSSOCookieLogin extends UserCookieLogin<PamirsUser> { //刷新令牌 private static String REFRESH_TOKEN = "refreshToken"; //系统id private static String CLIENT_ID = "client-id"; //访问令牌 private static String AUTHORIZATION = "Authorization"; private IUserLoginChecker checker; @Autowired private UserService userService; @Autowired private RedisTemplate<String, String> redisTemplate; @Override public String createSessionId(HttpServletRequest request, PamirsUser idModel) { return UUIDUtil.getUUIDNumberString(); } @Override public String type() { return UserLoginTypeEnum.COOKIE.value(); } @Override public PamirsUser resolveAndVerification(PamirsUserTransient user) { if (checker == null) { checker =…

    2023年11月24日
    2.0K00
  • 树型表格全量加载数据如何处理

    阅读该文档的前置条件 【界面设计器】树形表格 1.前端自定义表格组件 import { ActiveRecord, BaseElementWidget, Condition, Entity, SPI, TableWidget, ViewType } from '@kunlun/dependencies'; @SPI.ClassFactory( BaseElementWidget.Token({ type: ViewType.Table, widget: ['demo-tree-table'] }) ) export class TreeTableWidget extends TableWidget { // 默认展开所有层级 protected getTreeExpandAll() { return true; } // 关闭懒加载 protected getTreeLazy(): boolean { return false; } public async $$loadTreeNodes(condition?: Condition, currentRow?: ActiveRecord): Promise<Entity[]> { // 树表加载数据的方法,默认首次只查第一层的数据,这里去掉这个查询条件的参数condition,这样就会查所有层级数据 return super.$$loadTreeNodes(undefined, currentRow); } } 2. 注册layout import { registerLayout, ViewType } from '@kunlun/dependencies'; const install = () => { registerLayout( ` <view type="TABLE"> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="demo-tree-table" slot="table"> <element widget="expandColumn" slot="expandRow" /> <xslot name="fields" slotSupport="field" /> <element widget="rowActions" slot="rowActions" slotSupport="action" /> </element> </view> `, { viewType: ViewType.Table, model: "resource.resourceCity", // 变量,需要替换 actionName: "MenuuiMenu6f6005bdddba468bb2fb814a62fa83c6", // 变量,需要替换 } ); }; install();

    2024年8月17日
    1.8K00
  • 【DM】后端部署使用Dameng数据库(达梦)

    达梦数据库配置 驱动配置 达梦数据库的服务端版本和驱动版本需要匹配,建议使用服务端安装时提供的jdbc驱动,不要使用官方maven仓库中的驱动。 报错 表 xx 中不能同时包含聚集 KEY 和大字段,建表的时候就指定非聚集主键。SELECT * FROM V$DM_INI WHERE PARA_NAME = ‘PK_WITH_CLUSTER’;SP_SET_PARA_VALUE(1,’PK_WITH_CLUSTER’,0) Maven配置 DM8(目前maven仓库最新版本) <dm.version>8.1.2.192</dm.version> <dependency> <groupId>com.dameng</groupId> <artifactId>DmJdbcDriver18</artifactId> <version>${dm.version}</version> </dependency> PS: 8.1.3.12版本驱动需要手动上传到nexus仓库使用,本文包含该版本相关内容。 Maven配置 DM7 <dm7.version>7.6.1.120</dm7.version> <dependency> <groupId>com.dameng</groupId> <artifactId>Dm7JdbcDriver18</artifactId> <version>${dm7.version}</version> </dependency> PS: 7.6.1.120版本驱动需要手动上传到nexus仓库使用,本文包含该版本相关内容。 离线驱动下载 Dm7JdbcDriver18-7.6.1.120.jarDmJdbcDriver18-8.1.3.12.jar JDBC连接配置 pamirs: datasource: base: type: com.alibaba.druid.pool.DruidDataSource driverClassName: dm.jdbc.driver.DmDriver # url: jdbc:dm://127.0.0.1:5236/BASE?clobAsString=true&useUnicode=true&characterEncoding=utf8&compatibleMode=mysql url: jdbc:dm://127.0.0.1:5236?schema=BASE&clobAsString=true&columnNameUpperCase=false&useUnicode=true&characterEncoding=utf8&compatibleMode=mysql username: xxxxxx password: xxxxxx initialSize: 5 maxActive: 200 minIdle: 5 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true asyncInit: true validConnectionCheckerClassName: com.alibaba.druid.pool.vendor.OracleValidConnectionChecker validationQuery: SELECT 1 FROM DUAL 连接url配置 点击查看官方文档:DM JDBC 编程指南 连接串1 jdbc:dm://127.0.0.1:5236?schema=BASE&clobAsString=true&columnNameUpperCase=false&useUnicode=true&characterEncoding=utf8&compatibleMode=mysql PS:schema参数在低版本驱动区分大小写,高版本驱动不再区分大小写,为了避免错误,统一使用全大写。columnNameUpperCase参数与官方介绍不一致,为了避免错误,需要显式指定。 连接串2 jdbc:dm://127.0.0.1:5236/BASE?clobAsString=true&useUnicode=true&characterEncoding=utf8&compatibleMode=mysql PS:可能是未来更高版本中使用的连接串形式。 达梦数据库在不同驱动版本下需要使用不同的连接串进行处理,具体可参考下表:(使用错误的连接串将无法正常启动) Dm7JdbcDriver18版本 Build-Time 使用的连接串类型 是否支持指定schema schema是否区分大小写 是否可用 不可用原因 7.6.0.165 2019.06.04 1 否 是 否 不支持LocalDateTime类型 7.6.1.120(建议) 2022.09.14 1 是 是 是 – DmJdbcDriver18版本 Build-Time 使用的连接串类型 是否支持指定schema schema是否区分大小写 是否可用 不可用原因 8.1.2.192 2023.01.12 1 是 否 是 – 8.1.3.12(建议) 2023.04.17 2 是 否 是 – 方言配置 pamirs方言配置 pamirs: dialect: ds: base: type: DM version: 8 majorVersion: 8 pamirs: type: DM version: 8 majorVersion: 8 数据库版本 type version majorVersion 7-20220916 DM 7 20220916 8-20230418 DM 8 8 schedule方言配置 pamirs: event: schedule: dialect: type: DM version: 8 majorVersion: 8 type version majorVersion…

    2023年11月1日
    15.0K00
  • 如何在代码中使用自增ID和获取序列

    在使用继承IDModel或CodeModel时,id和code是系统默认自动生成, 默认值规则:ID–>分布式ID; CODE–>根据定义的SequenceConfig规则自动生成。 在特定情况下需要落库前先生成ID或者Code,这些场景下可参照如下代码示例 一、使用自增ID 单个字段设置方式 // 主键字段,可以使用mysql的自增能力 @Field.Integer @Field.PrimaryKey(keyGenerator = KeyGeneratorEnum.AUTO_INCREMENT) @Field.Advanced(batchStrategy = FieldStrategyEnum.NEVER) @Field(displayName = "id", summary = "Id字段,⾃增") private Long id; @Field.Integer @Field(displayName = "自增版本") @Field.Sequence(sequence = "SEQ", initial = 1) private Long version; 全局设置方式 该方式会作用到每一个存储模型的id字段,在application.yml配置文件中修改id的生成规则,查找配置项关键字key-generator,默认为DISTRIBUTION(分布式id),可修改为 AUTO_INCREMENT(自增id) 二、手动方式获取序列 获取方式示例1 /** * 在特定场景下需要手动生成Id或者code时,可参照这个示例 */ public void manualSetIdCode(){ DemoItem demoItem = new DemoItem(); //手动生成ID和code Object idObj = Spider.getDefaultExtension(IdGenerator.class).generate(PamirsTableInfo.fetchKeyGenerator(DemoItem.MODEL_MODEL)); demoItem.setId(TypeUtils.createLong(idObj)); Object codeObj = CommonApiFactory.getSequenceGenerator().generate("SEQ",DemoItem.MODEL_MODEL); String code = TypeUtils.stringValueOf(codeObj); demoItem.setCode(code); //…… } 获取方式示例2 1、在系统启动的时候初始化SequenceConfig package pro.shushi.pamirs.demo.core.init; 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.demo.core.constant.SeqConstants; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.api.dto.meta.Meta; import pro.shushi.pamirs.meta.enmu.SequenceEnum; import java.util.Map; /** * DemoMetadataEditor */ @Slf4j @Component public class DemoMetadataEditor implements MetaDataEditor { @Override public void edit(AppLifecycleCommand command, Map<String, Meta> metaMap) { InitializationUtil util = InitializationUtil.get(metaMap, DemoModule.MODULE_MODULE, DemoModule.MODULE_NAME); if (util == null) { log.error("获取初始化序列失败"); return; } bizSequence(util); } private void bizSequence(InitializationUtil util) { util.createSequenceConfig("申请单编码生成", SeqConstants.NABEL_SAMPLE_APPLY_SEQ, SequenceEnum.ORDERLY_SEQ, 8) .setStep(1) .setInitial(80000000L) .setIsRandomStep(false); util.createSequenceConfig("订单编码生成", SeqConstants.NABEL_SAMPLE_ORDER_SEQ_YP, SequenceEnum.ORDERLY_SEQ, 8) .setPrefix("YP") .setStep(1) .setInitial(80000000L) .setIsRandomStep(false); } } 2、在代码中使用序列 public static String getSaleOrderCode() { Object sequence = CommonApiFactory.getSequenceGenerator().generate(SequenceEnum.ORDERLY_SEQ.value(), SeqConstants.NABEL_SAMPLE_STRUCTURE_SEQ); return TypeUtils.stringValueOf(sequence); } public static String getApplyOrderCode(String prefix) { Object sequence = CommonApiFactory.getSequenceGenerator().generate(SequenceEnum.ORDERLY_SEQ.value(), SeqConstants.NABEL_SAMPLE_APPLY_SEQ); return…

    2024年5月25日
    2.3K00

Leave a Reply

Please Login to Comment