Nocobase 动态下拉值 基于sql查询结果

22 阅读2分钟

一共有两个办法, 一个是前端调用后端api执行, 另一个是在前端直接执行sql(但会受权限影响, 非管理员权限访问会失败), 建议采用第一个:

一 前端调用后端api:

  1. 实现后端, 后端根据自己的开发语言自己实现sql执行功能. 我的是post方法, 传入sql参数
  2. 选择对应需要配置的字段,添加 "事件流" ,选择 "执行javascript"
  3. 添加代码, 向后端发情请求
// 查询 sql 结果作为下拉选项, label作为展示值, value作为传输值
const sqlQuery = `select *from user`;

// 使用您提供的实际密码
const BASE_API_URL = 'http://47.112.178.78:8899/meituan/sql/sql_ex';

try {
  // 构建包含查询参数的完整URL(根据您的curl示例,参数通过URL查询字符串传递)
  const encodedSql = encodeURIComponent(sqlQuery);
  const fullUrl = `${BASE_API_URL}?sql=${encodedSql}`;
  
  const response = await ctx.request({
    url: fullUrl,
    method: 'POST',
    headers: {
      'Content-Length': '0',
      'accept': 'application/json'
    }
  });
  
  // 检查API响应状态
  if (response.status !== 200) {
    throw new Error(ctx.t('API返回错误状态: {{status}}', { status: response.status }));
  }
  
  // 获取API返回的结果数据
  const result = response.data?.data || response.data;
  
  // 获取当前字段的 UI 配置
  const collectionField = await ctx.getVar('ctx.collectionField');
  
  if (!collectionField || !collectionField.uiSchema) {
    console.warn(ctx.t('未找到有效的 collectionField 配置'));
    return;
  }
  
  // 将查询结果注入为枚举选项
  collectionField.uiSchema.enum = result;
  
  // 启用搜索功能,按 label 过滤
  collectionField.uiSchema['x-component-props'] = {
    ...collectionField.uiSchema['x-component-props'],
    showSearch: true,
    optionFilterProp: 'label'
  };
  
  console.log(ctx.t('字段选项已成功更新'));
} catch (error) {
  console.error(ctx.t('调用API失败:'), error);
  ctx.message.error(ctx.t('获取字段选项失败,请检查API配置'));
}

二 前端执行sql

  1. 选择对应需要配置的字段,添加 "事件流" ,选择 "执行javascript"

image.png

  1. 添加代码, 修改第一段的为自己想要结果的sql即可
// 查询 sql 结果作为下拉选项, label作为展示值, value作为传输值
const sqlQuery = `
  SELECT 
    COLUMN_NAME AS value,
    COLUMN_NAME AS label
  FROM 
    information_schema.COLUMNS
`;

// 执行 SQL,获取字段选项列表
const result = await ctx.sql.run(sqlQuery, { type: 'selectRows' });


// 获取当前字段的 UI 配置
const collectionField = await ctx.getVar('ctx.collectionField');


// 将查询结果注入为枚举选项
collectionField.uiSchema.enum = result;

// 启用搜索功能,按 label 过滤
collectionField.uiSchema['x-component-props'] = {
  ...collectionField.uiSchema['x-component-props'],
  showSearch: true,
  optionFilterProp: 'label'
};