「前端」 获取当前用户信息以及语言

概述

TopBarService 是用于管理用户信息和多语言配置的工具类,提供以下核心功能:

  • 用户信息查询(含缓存机制)
  • 当前语言状态获取
  • 可用语言列表查询
  • 语言切换操作

快速开始

// 基础使用示例
import { TopBarService } from '@kunlun/dependencies';

// 获取用户信息(自动缓存)
const userInfo = await TopBarService.getUserInfo();

// 获取当前语言配置
const currentLang = await TopBarService.getCurrentLang();

// 查询支持的语言列表
const languages = await TopBarService.queryLanguageList();

// 激活指定语言
await TopBarService.activeLang('zh_CN');

API 详解

方法功能说明

方法名称 描述 参数 返回值
getUserInfo 获取当前用户信息(自动缓存) 用户信息对象
queryUserInfo 强制获取最新用户信息 最新用户信息对象
getCurrentLang 获取当前激活的语言配置 语言配置对象 / undefined
queryLanguageList 获取所有可用语言列表 语言列表数组
activeLang 激活指定语言 语言 ID (string) 更新后的语言配置对象

Oinone社区 作者:汤乾华原创文章,如若转载,请注明出处:https://doc.oinone.top/frontend/20744.html

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

(0)
汤乾华的头像汤乾华数式员工
上一篇 2025年3月19日 pm3:56
下一篇 2025年3月21日 pm5:46

相关推荐

  • 前端自定义左树右表中的树

    在 oinone 平台中,提供了默认的左树右表的视图,用户可以通过界面设计器配置,默认的树视图不一定满足所有需求,尤其当需要自定义功能或复杂的交互时,我们可以通过自定义视图来实现更灵活的展现。 本文将带你一步步了解如何自定义左树右表视图中的树组件。 自定义树视图 1. 使用界面设计器配置视图 首先,我们需要通过界面设计器生成基础的左树右表视图。界面设计器允许用户根据不同需求进行拖拽配置,快速创建可视化界面。 配置完视图之后,我们可以重写左侧的树组件。Oinone 的默认树组件是 TableSearchTreeWidget,通过自定义的方式,我们可以实现更高级的功能。 2. 重写 TableSearchTreeWidget import { BaseElementWidget, SPI, TableSearchTreeWidget, ViewType } from '@kunlun/dependencies'; import CustomTableSearchTree from './CustomTableSearchTree.vue'; @SPI.ClassFactory( BaseElementWidget.Token({ viewType: [ViewType.Table, ViewType.Form], widget: 'tree', model: 'resource.k2.Model0000000100' // 改成自己的模型 }) ) export class CustomTableSearchTreeWidget extends TableSearchTreeWidget { public initialize(props) { super.initialize(props); this.setComponent(CustomTableSearchTree); return this; } } 3. 定义 Vue 树组件 接下来,我们来实现 CustomTableSearchTree.vue 组件。这个组件将处理树的数据加载、节点选中等逻辑。你可以根据项目的需要修改其中的交互逻辑或 UI 设计。 <template> <a-tree :load-data="onLoadData" :tree-data="treeData" @select="onSelected" /> </template> <script lang="ts"> import { OioTreeNode, TreeUtils } from '@kunlun/dependencies'; import { computed, defineComponent } from 'vue'; export default defineComponent({ props: { rootNode: { type: Object }, loadData: { type: Function, required: true }, onSelected: { type: Function, required: true } }, setup(props) { // // 计算树的数据源,使用 TreeUtils 处理 const treeData = computed(() => { return TreeUtils.fillLoadMoreAction([…(props.rootNode?.children || [])]); }); // 异步加载子节点 const onLoadData = async (node) => { return await props.loadData(node.dataRef); }; // 处理节点选中事件 const onSelected = ( selectedKeys: string[], e: { nativeEvent: PointerEvent; node: { dataRef: OioTreeNode }; selected: boolean } ) => { props.onSelected?.(e.node.dataRef, e.selected); }; return { treeData, onLoadData, onSelected }; } }); </script> 4. 自定义…

    2024年10月21日
    2.4K00
  • 如何自定义点击导出动作绑定指定模板

    介绍 平台默认的导出会打开弹窗,然后在弹窗内的视图选择是用模板方式导出还是选字段导出,但是有时候有部分场景希望点击导出动作后直接进入导出流程,导出指定的某个模板,我们可以通过覆写打开弹窗的动作来实现该功能。 本文档参考了 表格页自定义按钮如何获取搜索区域的查询条件 代码示例 以下代码大部分场景只需要修改其中excelTplName更换模板即可,另外如何想增加复用性,还可以将该属性改为从元数据的配置中获取。 import { ActionType, BaseActionWidget, BaseElementListViewWidget, BooleanHelper, ClickResult, Condition, ExcelExportTask, FILE_MODULE_NAME, getSessionPath, GraphqlHelper, http, IQueryPageResult, ISort, queryDslWidget, ReturnPromise, RuntimeServerAction, ServerActionWidget, SPI, SubmitValue, SYSTEM_MODULE_NAME, translateValueByKey, UrlHelper, ViewActionTarget, Widget } from '@kunlun/dependencies'; import { OioNotification } from '@kunlun/vue-ui-antd'; @SPI.ClassFactory( BaseActionWidget.Token({ actionType: [ActionType.View], target: [ViewActionTarget.Dialog], model: 'ys0328.k2.Model0000000453', name: 'internalGotoListExportDialog' }) ) export class DemoExportActionWidget extends ServerActionWidget { /** * excel导出模板名称 * @protected */ protected excelTplName = '演示抽屉跳转链接导出'; /** * 导出任务的模型编码 * @protected */ protected exportTaskModel = 'excelExportTask'; /** * 导出任务的方法 * @protected */ protected exportTaskFun = 'createExportTask'; /** * * 是否是同步导出 */ @Widget.Reactive() protected get syncExport() { return BooleanHelper.isTrue(this.getDsl().sync) || !true; } protected async executeAction(action: RuntimeServerAction, parameters: SubmitValue): Promise<ClickResult> { const workbookId = await this.getWorkbookId(); if (!workbookId) { return false; } let task = { workbookDefinition: { id: workbookId } } as ExcelExportTask; // 从平台内置的方法获取搜索区域的条件 const { condition } = this.getSearchRsqlAndQueryParams(); // 排序规则 let sortList = [] as ISort[]; const baseViewWidget = Widget.select(this.rootHandle); const listViewWidget = queryDslWidget(baseViewWidget?.getChildrenInstance(), BaseElementListViewWidget); if (listViewWidget) { sortList = listViewWidget.sortList; } return this.export(task, condition, sortList); } protected getUploadBodyGql(id: string, condition: string | Condition, sortList:…

    2024年10月9日
    1.4K00
  • 【前端】IOC容器(v4)

    什么是IOC容器? IOC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合,更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IOC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的使程序的整个体系结构变得非常灵活。在运行期,在外部容器动态的将依赖对象注入组件,当外部容器启动后,外部容器就会初始化。创建并管理对象实例,以及销毁,这种应用本身不负责依赖对象的创建和维护,依赖对象的创建和维护是由外部容器负责的称为控制反转。 IOC(控制反转)和DI(依赖注入) IOC(Inversion of Control, 控制反转):通过外部容器管理对象实例的一种思想。DI(Dependency Injection, 依赖注入):IOC的一种实现方式。 作者简述 IOC是Spring框架(一种以Java为语言开发的框架)的核心,并贯穿始终。其面向接口的开发能力,使得服务调用方和服务提供方可以做到完全解耦,只要遵循接口定义的规则进行调用,具体服务的实现可以是多样化的。 对于前端,我们使用inversify进行了IOC的实现。其强大的解耦能力可以使得平台进行大量的抽象,而无需关系具体的实现。 接下来,我们将介绍IOC在开发中的基本运用。 API 为了方便起见,我们将IOC相关功能与组件SPI的调用方式放在了一起。(更高版本的平台版本将自动获得该能力) export class SPI { /** * register singleton service */ public static Service; /** * autowired service property/parameter in service */ public static Autowired; /** * service construct after execute method */ public static PostConstruct; /** * autowired service in widget */ public static Instantiate; /** * autowired services in widget */ public static Instantiates; /** * service construct after execute method in widget */ public static InstantiatePostConstruct; } 创建第一个服务 service/ProductService.ts import { ServiceIdentifier } from '@kunlun/dependencies'; /** * 产品 */ export interface Product { id: string; name: string; } /** * 产品服务 */ export interface ProductService { /** * 获取产品列表 */ getProducts(): Promise<Product[]>; /** * 通过ID获取产品 * @param id 产品ID */ getProductById(id: string): Promise<Product | undefined>; } /** * 产品服务Token */ export const ProductServiceToken = ServiceIdentifier<ProductService>('ProductService'); service/impl/ProductServiceImpl.ts import { SPI } from '@kunlun/dependencies'; import { Product, ProductService, ProductServiceToken } from '../ProductService'; @SPI.Service(ProductServiceToken) export class ProductServiceImpl implements ProductService { public async getProducts(): Promise<Product[]> { // request api get products return []; } public async getProductById(id:…

    前端 2023年11月1日
    1.0K00
  • 如何实现页面间的跳转

    介绍 在日常的业务中,我们经常需要在多个模型的页面之间跳转,例如从商品的行可以直接点击链接跳转到类目详情,还有查看该订单发起的售后单列表,这里将给大家展示如何在oinone中如何实现这些功能。 方法一、通过界面设计器的无代码能力配置 表格行跳转到表单页/详情页 拖入一个跳转动作到表格行,保存动作后,在左侧的动作属性面板底部有个请求配置,里面的上下文属性就是配置跳转参数的地方,点击添加按钮可以增加一行参数 点击添加按钮后,可以看到新增了一行,行内有2个输入框,左侧输入框为目标视图模型的字段,右侧输入框为当前视图模型的表达式 注意 表达式中activeRecord关键字代表当前行的数据对象 “上下文”相关知识点 当前页面的模型和跳转后的页面模型相同的情况下,会字段带上当前行数据的id作为路由参数 上下文是从当前页面跳转到下个页面带的自定义参数 上下文会作为跳转后的页面数据加载函数的入参,后端的该函数需要根据该条件查询到数据返回给前端,典型的例子就是编辑页,根据id查询对象的其他字段信息返回 跳转后页面的数据加载函数可以在动作场景的时候选择加载函数,也可以在页面的加载函数处设置 方法二、通过低代码方式在自定义代码中调用 oinone提供了内置函数executeViewAction实现该功能 import { DefaultComparisonOperator, executeViewAction, QueryExpression, RuntimeViewAction, ViewActionTarget, ViewType } from '@kunlun/dependencies'; export class JumpActionWidget { protected goToObjectView() { executeViewAction( { viewType: ViewType.Form, moduleName: 'resource', model: 'resource.ResourceCountry', name: 'redirectUpdatePage', target: ViewActionTarget.Router } as RuntimeViewAction, undefined, undefined, { // 此处为id参数,目前只有表单和详情页需要 id: '12223', // 此处为上下文参数,context内对象的key是目标页面需要传递的默认值 context: JSON.stringify({code: 'xxx'}), // 此处为跳转后左侧菜单展开选中的配置 menu: JSON.stringify({"selectedKeys":["国家"],"openKeys":["地址库","地区"]}) } ); } protected goToListView() { const searchConditions: QueryExpression[] = []; searchConditions.push({ leftValue: ['countryCode'], // 查询条件的字段 operator: DefaultComparisonOperator.EQUAL, right: 'CN' // 字段的值 }); executeViewAction( { viewType: ViewType.Table, moduleName: 'resource', model: 'resource.ResourceCity', name: 'resource#市', target: ViewActionTarget.OpenWindow } as RuntimeViewAction, undefined, undefined, { // searchConditions相当于domain,不会随页面搜索项重置动作一起被清空 searchConditions: encodeURIComponent(JSON.stringify(searchConditions)), // searchBody的字段会填充搜索区域的字段组件,会随页面搜索项重置动作一起被清空 searchBody: JSON.stringify({code: 'CN'}), menu: JSON.stringify({"selectedKeys":["国家"],"openKeys":["地址库","地区"]}) } ); } } 扩展知识点 为什么executeViewAction跳转到的新页面不是入参的moduleName属性对应的模块? 答:跳转后所在的模块优先级为: 第一个入参的resModuleName属性对应的模块 执行executeViewAction时所在的模块 第一个入参的moduleName属性对应的模块 如何快速获取选中菜单的值? 答:先通过页面菜单手动打开页面,然后在浏览器自带调试工具的控制台执行decodeURIComponent(location.href),其中的menu参数就是我们需要的值

    2024年5月13日
    2.5K00
  • 前端自定义组件之多页面步骤条

    本文将讲解如何通过自定义,实现多页面的步骤条组件。其中每个步骤的元素里都对应界面设计器的一个页面。以下是代码实现和原理分析。 代码实现 NextStepWidget 多页面步骤条 ts 组件 import { CallChaining, createRuntimeContextByView, customMutation, customQuery, RuntimeView, SPI, ViewCache, Widget, DefaultTabsWidget, BasePackWidget } from '@oinone/kunlun-dependencies'; import { isEmpty } from 'lodash-es'; import { MyMetadataViewWidget } from './MyMetadataViewWidget'; import NextStep from './NextStep.vue'; import { IStepConfig, StepDirection } from './type'; @SPI.ClassFactory(BasePackWidget.Token({ widget: 'NextStep' })) export class NextStepWidget extends DefaultTabsWidget { public initialize(props) { this.titles = props.template?.widgets?.map((item) => item.title) || []; props.template && (props.template.widgets = []); super.initialize(props); this.setComponent(NextStep); return this; } @Widget.Reactive() public get invisible() { return false; } // 配置的每一步名称 @Widget.Reactive() public titles = []; // region 上一步下一步配置 // 步骤配置,切换的顺序就是数组的顺序,模型没有限制 @Widget.Reactive() public get stepJsonConfig() { let data = JSON.parse( this.getDsl().stepJsonConfig || '[{"model":"resource.ResourceCountry","viewName":"国家form"},{"model":"resource.ResourceProvince","viewName":"省form"},{"model":"resource.ResourceCity","viewName":"市form"}]' ); return data as IStepConfig[]; } // 切换上一步下一步 @Widget.Method() public async onStepChange(stepDirection: StepDirection) { // 没有激活的,说明是初始化,取第一步 if (!this.activeStepKey) { const step = this.stepJsonConfig[0]; if (step) { this.activeStepKey = `${step.model}_${step.viewName}`; await this.initStepView(step); } return; } // 获取当前步骤的索引 if (this.currentActiveKeyIndex > -1) { await this.onSave(); // 获取下一步索引 const nextStepIndex = stepDirection === StepDirection.NEXT ? this.currentActiveKeyIndex + 1 : this.currentActiveKeyIndex – 1; // 在索引范围内,则渲染视图 if (nextStepIndex >= 0 && nextStepIndex < this.stepJsonConfig.length) { const nextStep = this.stepJsonConfig[nextStepIndex];…

    2025年7月21日
    63800

Leave a Reply

登录后才能评论