Skip to content

组件上下文:环境变量与工具函数

在 Neo 页面中,自定义组件运行时会注入页面级数据用户数据环境对象工具函数等,自定义组件中可直接使用这些环境变量和工具函数。

props 上的位置
作用
data(及下文 __Neo* 字段)
当前页注入的用户、系统、页面元信息等
env.ctx
平台对象 CTX,系统 / 用户 / UI / 工具 / api
keyIdentifier$schema$com
当前组件实例标识;设计时属性区另见 $com
  • 类组件:通过 this.props.datathis.props.env.ctx 等访问。
  • 函数组件:通过入参 props 或解构 const { data, env } = props 使用;若使用 Hooks,在依赖中传入完整 envenv?.ctx 时需注意引用稳定性。

页面数据与用户、租户信息

以下字段均在 this.props.data 上:

用途
路径
说明
当前用户
this.props.data.__NeoCurrentUser
用户信息
系统信息
this.props.data.__NeoSystemInfo
租户相关系统信息
页面信息
this.props.data.__NeoPageInfo
含页面 ID 等页面级元数据

使用示例(当前用户、系统与页面):

js
// 当前用户(页面注入的用户对象,字段以实际平台为准,常见含 id、name 等)
const currentUser = this.props.data?.__NeoCurrentUser;
if (currentUser) {
  console.log(currentUser.id, currentUser.name);
}

// 租户与系统信息
const systemInfo = this.props.data?.__NeoSystemInfo;

// 页面元数据(含页面 ID 等,字段以平台实际返回为准)
const pageInfo = this.props.data?.__NeoPageInfo;

组件 ID(keyIdentifier)

使用场景
取值位置
运行时设计时画布区
this.props 上的 keyIdentifier;也可从 this.props.$schema 中解析
设计时属性面板
this.props.$com.keyIdentifier

使用示例:

js
// 运行时 / 画布:组件实例唯一标识
const curCmpKey = this.props.keyIdentifier;

// 设计时属性面板
const curCmpKey = this.props.$com?.keyIdentifier;

全局对象 CTX(props.env.ctx

平台已将 CTX 注入到 props.env.ctx。下文按分类列出可用能力;标注为「只读」的均为属性访问,其余为函数调用。

系统(system)

名称 / API
类型
说明
读写
language
属性
当前用户使用的系统语言
只读
timeZone
属性
当前用户使用的时区
只读
clientType
属性
访问端类型:Web(网页)、App(移动)、WeCom(企微)、DingTalk(钉钉)
只读
tenantId
属性
当前租户 ID
只读
tenantName
属性
当前租户名称
只读
currencies
属性
当前租户已启用的货币类型
只读
systemType
属性
业务系统类型,例如 crmprm
只读
logout()
函数
登出并回到登录页
getCurrentDate(format?)
函数
获取当前系统时间;可通过 format 指定返回格式,默认包含年月日时分

使用示例(语言、租户、logout):

js
const ctx = this.props.env?.ctx;
if (!ctx) return;

const { language, tenantId, tenantName } = ctx.system;
// 登出并回到登录页(常用于自定义「退出」按钮)
ctx.system.logout();

当前用户(user)

名称 / API
类型
说明
读写
name
属性
用户姓名
只读
currency
属性
用户货币类型
只读
id
属性
用户 ID
只读
primaryFunctionalId
属性
主职能 ID
只读
functionals
属性
已分配职能列表,元素形如 { id, name, isMain }
只读
departmentId
属性
部门 ID
只读
departmentName
属性
部门名称
只读
email
属性
邮箱
只读
phoneNumber
属性
手机号
只读

使用示例:

js
const user = this.props.env?.ctx?.user;
if (!user) return;

const { id, name, email, departmentName } = user;
// 按业务需要读取职能、部门等
const mainFunctional = user.functionals?.find((f) => f.isMain);

界面(ui)

名称 / API
类型
说明
读写
showToast(type, msg, time?)
函数
轻提示。typesuccess | warning | errormsg 为文案;time 为停留秒数,默认 1
confirm(options)
函数
确认弹窗,参数见下方
openIframe(options)
函数
以弹层形式打开 iframe,可拖动;参数见下方
showLoading()
函数
当前页显示遮罩与 loading
hideLoading()
函数
关闭当前页遮罩与 loading
openPickerList(options)
函数
打开实体 Picker(查找)页;参数见下方
navigatePageTo({ url, isNewWindow? })
函数
打开指定页面;可在当前页跳转或新标签打开,默认新标签

confirm 参数:

ts
confirm({
  title: string;       // 标题
  msg: string;         // 正文
  width?: string;      // 宽度,默认约 400px
  onOk: () => void;    // 确认
  onCancel: () => void; // 取消
});

openIframe 参数:

ts
openIframe({
  devPageKey?: string;           // 内部开发页:入口页 apiKey;外部页配合 url
  url: string;                   // 自定义页 URL
  title: string;                 // 弹窗标题
  height?: string | number;      // 高度,默认 300px
  width?: string | number;       // 宽度,默认 400px
  showFooter?: boolean;          // 是否显示 footer,默认 false
  onOk?: Function;
  onCancel?: Function;           // 取消与右上角关闭
  showCloseButton?: boolean;     // 是否显示右上角关闭,默认 true
});

openPickerList 参数:

ts
openPickerList({
  objectApiKey: string;                    // 实体 ApiKey
  listView: string;                        // 列表视图 apiKey,如 "customEntity2c_view_2"
  selectionMode?: "single" | "multiple"; // 单选 / 多选
  conditions?: {
    apiKey: string;
    type: FilterOperator;
    value: any; // 多值用逗号分隔表示 OR
  }[];
  orderBy?: {
    field: string;
    order?: "asc" | "desc";
  };
  title?: string; // Picker 标题
});

典型场景:在销售机会上为关联字段打开客户的 Picker 页。

使用示例:

js
const ui = this.props.env?.ctx?.ui;
if (!ui) return;

ui.showToast('success', '保存成功', 2);

ui.confirm({
  title: '确认删除',
  msg: '删除后不可恢复,是否继续?',
  onOk: () => {
    // 执行删除
  },
  onCancel: () => {},
});

工具函数(util)

名称 / API
类型
说明
读写
log(any)
函数
控制台 log
warn(any)
函数
控制台 warn
info(any)
函数
控制台 info
error(any)
函数
控制台 error
setTimeout(fn, time)
函数
与标准 setTimeout 类似
setInterval(fn, time)
函数
与标准 setInterval 类似
isEmpty(any)
函数
判空;支持基本类型、数组、对象;{}[] 视为空
urlParams
属性
当前页 URL 的查询参数(如 ?a=1&b=2 对应可解析的键值),用于按入参控组件行为、与深度链接等场景配合
openAIChat(any)
函数
打开 AI 对话框方法

使用示例(urlParamsisEmpty):

js
const util = this.props.env?.ctx?.util;
if (!util) return;

// 读取当前页 URL 查询参数,例如 ?orderId=123
const orderId = util.urlParams?.orderId;

if (!util.isEmpty(orderId)) {
  util.log('orderId', orderId);
}

示例

使用 openAIChat 增加 打开 AI 对话框的按钮:

import * as React from 'react';
// @ts-ignore
import { BaseCmp } from 'neo-ui-common';

export default class openChatPageBtn extends BaseCmp<
  openChatPageBtnProps,
  chatPageStates
> {
  constructor(props: openChatPageBtnProps) {
    super(props);
  }

  openChatPage() {
    const { env, aiQuery, agentApiKey } = this.props;
    const openAIChat = env?.ctx?.util?.openAIChat;
    if (!openAIChat) {
      return;
    }
    // 打开AI对话页
    openAIChat({
      query: aiQuery || '请总结一下本周数据变化',
      agentApiKey: agentApiKey || 'sales_assistant_agent',
    });
  }

  render() {
    const { className, placeholder } = this.props;

    return (
      <div className={`openChatPageBtn__c-container ${className || ''}`}>
        <button
          className="openChatPageBtn-button"
          onClick={() => this.openChatPage()}
        >
          <span className="openChatPageBtn-icon"></span>
          <span className="openChatPageBtn-text">
            {placeholder || '打开AI对话页'}
          </span>
        </button>
      </div>
    );
  }
}

接口(api)

下文示例中的 ctxthis.props.env.ctx(与上文的 CTX 为同一对象)。

使用示例(request):

js
const ctx = this.props.env?.ctx;
if (!ctx?.api?.request) return;

ctx.api
  .request({
    url: '/your/open/or/custom/api',
    method: 'POST',
    headers: {},
    data: { foo: 1 },
  })
  .then((res) => {
    ctx.util?.log(res);
  });
名称 / API
类型
说明
读写
ctx.api.openCreateForm({ ... })
函数
打开新建表单,参数见下方
ctx.api.openEditForm({ ... })
函数
打开编辑表单
ctx.api.openCloneForm({ ... })
函数
打开复制表单
ctx.api.openListPage({ ... })
函数
打开对象列表页
request({ url, headers, method, data })
函数
调用服务端接口(仅开放接口或自定义接口)

新建表单 openCreateForm

  • objectApiKey:对象 API 名称
  • busiType:业务类型 API 名称
  • defaultValues:字段默认值(仅支持布局上出现的字段)。关联字段需传入 { id, name } 形式的对象。

示例:

js
ctx.api.openCreateForm({
  objectApiKey: 'xxx',
  busiType: 'defaultBusiType',
  defaultValues: {
    name: 'AME',
    parent__c: { id: '记录ID', name: '显示名称' },
  },
});

编辑表单 openEditForm

  • objectApiKeybusiType:同上
  • recordId:记录 ID
js
ctx.api.openEditForm({
  objectApiKey: 'zhu__c',
  busiType: 'defaultBusiType',
  recordId: 3710606526529990,
});

复制表单 openCloneForm 参数与 openEditForm 相同,用于基于已有记录复制一条数据。

js
ctx.api.openCloneForm({
  objectApiKey: 'zhu__c',
  busiType: 'defaultBusiType',
  recordId: 3710606526529990,
});

列表页 openListPage

  • objectApiKey:对象 API 名称
  • listView:视图 API 名称
  • config.isNewTab:是否在新页签打开
js
ctx.api.openListPage({
  objectApiKey: 'customEntity111__c',
  listView: 'customEntity111__c_view_all',
  config: { isNewTab: true },
});

小结

  • 组件上下文:业务 props 之外,由平台注入的页面数据(data)、运行环境能力(env.ctx / CTX)与组件标识(keyIdentifier / $schema / $com)等,共同构成运行时的使用环境;与构建工具里的「环境变量」含义不同。
  • 页面级数据从 this.props.data__NeoCurrentUser__NeoSystemInfo__NeoPageInfo 读取。
  • 组件标识 keyIdentifier 在运行/画布侧看 this.props$schema,设计时属性区看 this.props.$com.keyIdentifier
  • 系统 UI、用户态、工具方法与业务 API 统一通过 props.env.ctxCTX)访问。