数据范围能添加变量吗?

如图 我的插件需要在这里添加一个页面变量 没看到相关的开发文档 ,这个可以实现吗?

用2.0的事件流

不行呦 我是要把企业微信侧边栏的sdk过来的客户信息添加到变量里面



群信息已经拿到了,需要通过插件弄到这个选择器里面

暂时没有这方面的文档,建议看下代码

NocoBase 自定义变量开发指南

概述

NocoBase 支持在表格、详情、表单等区块的数据范围中使用变量。通过 app.registerVariable() API,插件可以注册自定义变量,让用户在配置数据范围时选择使用。

内置变量

NocoBase 内置了以下变量:

变量 说明 示例
$user 当前用户 {{$user.id}}, {{$user.nickname}}
$nRole 当前角色 {{$nRole.name}}
$nDate 日期时间 {{$nDate.now}}
$nRecord 当前记录 {{$nRecord.id}}
$nForm 当前表单 {{$nForm.fieldName}}
$nPopupRecord 弹窗记录 {{$nPopupRecord.id}}
$nURLSearchParams URL参数 {{$nURLSearchParams.id}}

注册自定义变量

1. 创建变量 Hook 文件

在插件的 src/client/variables/ 目录下创建变量 Hook:

// src/client/variables/useMyVariable.ts

import { useMemo } from 'react';

/**
 * 变量选项 Hook
 * 返回变量在选择器中的显示配置
 */
export const useMyVariableOption = () => {
  const option = useMemo(() => {
    return {
      value: '$myVar',        // 变量标识符,必须以 $ 开头
      label: '我的变量',       // 显示名称
      children: [             // 子选项(可选)
        {
          value: 'field1',
          label: '字段1',
        },
        {
          value: 'field2',
          label: '字段2',
        },
      ],
    };
  }, []);

  return {
    option,
    visible: true,  // 是否显示此变量
  };
};

/**
 * 变量上下文 Hook
 * 返回变量的实际值
 */
export const useMyVariableCtx = () => {
  // 返回变量的实际值
  return {
    field1: '值1',
    field2: '值2',
  };
};

2. 导出变量 Hook

// src/client/variables/index.ts

export * from './useMyVariable';

3. 在插件中注册变量

// src/client/plugin.tsx

import { Plugin } from '@nocobase/client';
import { useMyVariableOption, useMyVariableCtx } from './variables';

export class MyPluginClient extends Plugin {
  async load() {
    // 注册自定义变量
    this.app.registerVariable({
      name: '$myVar',                    // 变量名,必须与 option.value 一致
      useOption: useMyVariableOption,    // 选项 Hook
      useCtx: useMyVariableCtx,          // 上下文 Hook
    });
  }
}

export default MyPluginClient;

API 详解

Variable 接口

interface Variable {
  /** 变量唯一标识符,必须以 $ 开头 */
  name: string;
  
  /** 变量选项 Hook,返回显示配置 */
  useOption: () => { 
    option: VariableOption; 
    visible?: boolean;  // 是否显示,默认 true
  };
  
  /** 变量上下文 Hook,返回变量的实际值 */
  useCtx: () => any;
}

VariableOption 接口

interface VariableOption {
  /** 变量值,用于生成变量字符串 */
  value: string | number;
  
  /** 显示标签 */
  label?: React.ReactNode;
  
  /** 是否禁用 */
  disabled?: boolean;
  
  /** 子选项 */
  children?: VariableOption[];
}

完整示例:企业微信侧边栏变量

变量 Hook

// src/client/variables/useWecomVariable.ts

import { useMemo } from 'react';

// 全局存储上下文
declare global {
  interface Window {
    __WECOM_SIDEBAR_CONTEXT__?: {
      groupId?: string;
      groupName?: string;
      customerId?: string;
      customerName?: string;
    };
  }
}

export const useWecomVariableOption = () => {
  const option = useMemo(() => {
    return {
      value: '$wecom',
      label: '企业微信',
      children: [
        { value: 'groupId', label: '群ID' },
        { value: 'groupName', label: '群名' },
        { value: 'customerId', label: '客户ID' },
        { value: 'customerName', label: '客户名' },
      ],
    };
  }, []);

  return {
    option,
    visible: true,
  };
};

export const useWecomVariableCtx = () => {
  const ctx = window.__WECOM_SIDEBAR_CONTEXT__ || {};
  
  return {
    groupId: ctx.groupId || '',
    groupName: ctx.groupName || '',
    customerId: ctx.customerId || '',
    customerName: ctx.customerName || '',
  };
};

插件注册

// src/client/plugin.tsx

import { Plugin } from '@nocobase/client';
import { useWecomVariableOption, useWecomVariableCtx } from './variables';

export class PluginWecomClient extends Plugin {
  async load() {
    // 注册企业微信变量
    this.app.registerVariable({
      name: '$wecom',
      useOption: useWecomVariableOption,
      useCtx: useWecomVariableCtx,
    });
  }
}

export default PluginWecomClient;

使用变量

注册后,用户可以在以下位置使用变量:

  1. 表格区块 - 设置数据范围
  2. 详情区块 - 设置数据范围
  3. 表单区块 - 设置数据范围、字段默认值
  4. 筛选器 - 设置筛选条件

变量格式:{{$变量名.字段名}}

示例:

  • {{$wecom.groupId}} - 获取企业微信群ID
  • {{$wecom.customerName}} - 获取企业微信客户名
  • {{$user.id}} - 获取当前用户ID

动态变量值

如果变量值需要从 API 获取或动态计算,可以在 useCtx 中使用 React Hooks:

export const useMyVariableCtx = () => {
  const [data, setData] = useState({});
  const api = useAPIClient();
  
  useEffect(() => {
    api.request({
      url: '/my-api:getData',
      method: 'get',
    }).then((res) => {
      setData(res?.data?.data || {});
    });
  }, []);
  
  return data;
};

条件显示变量

可以根据条件决定是否显示变量:

export const useMyVariableOption = () => {
  const currentUser = useCurrentUserContext();
  
  // 只有管理员才能看到此变量
  const isAdmin = currentUser?.data?.data?.roles?.some(
    (r: any) => r.name === 'admin'
  );

  const option = useMemo(() => ({
    value: '$adminVar',
    label: '管理员变量',
    children: [
      { value: 'secret', label: '敏感数据' },
    ],
  }), []);

  return {
    option,
    visible: isAdmin,  // 只有管理员可见
  };
};

注意事项

  1. 变量名必须以 $ 开头,如 $wecom$myVar
  2. 变量名必须唯一,重复注册会被忽略并打印警告
  3. useOption 和 useCtx 是 React Hooks,遵循 Hooks 规则
  4. 变量值应该是可序列化的,避免使用函数或循环引用
  5. 子选项的 value 会拼接到变量路径中,如 {{$wecom.groupId}}

调试

在浏览器控制台中可以查看已注册的变量:

// 获取 NocoBase 应用实例
const app = window.__NOCOBASE_APP__;

// 查看所有注册的变量
console.log(app.getVariables());

相关文件

  • 变量核心实现:@nocobase/client/src/variables/
  • 变量选择器组件:@nocobase/client/src/schema-component/antd/variable/
  • 变量选项 Hook:@nocobase/client/src/schema-settings/VariableInput/hooks/

这个只能用于V1页面