权限同步API实战流程

本文档介绍如何通过 API 完成角色权限配置、单用户同步、用户级权限覆盖、认证器绑定和 AI 员工权限同步。根据是否需要绑定角色,可以选择角色级接口或用户级接口。

场景描述

假设当前的空间 ID 为 default,有一张商品表,sid 为 dim_prods_default

现在需要添加一个「店长」角色,让该角色默认只能查看「产品类型 = 电子产品」的数据,并控制部分指标的可见范围;同时为个别用户配置更细粒度的用户级权限覆盖,并提前绑定飞书、企业微信等认证器身份。

接口选择

使用场景接口说明
创建或更新角色,同时同步角色权限、用户绑定、数据行范围或 AI 员工yiask_roles:updateOrCreateWithPermissionsusers 是当前角色的全量用户列表,可同时创建或更新多个用户
创建或更新单个用户,同时同步用户级权限和认证器身份yiask_users:updateOrCreateWithPermissions不绑定角色,也不写入 usersYiaskCollections

如果用户必须同时绑定角色或同步 dataRowScope,请使用角色级接口;如果只需维护单个用户及其用户级权限,或需要预先建立认证器映射,请使用用户级接口。

API 通用配置

获取 API Key

管理员账号 → 右上角⚙️按钮 → API密钥,生成一个密钥。

必需的请求头

所有 API 请求都需要包含以下请求头:

Authorization: Bearer <YOUR_TOKEN>
X-SPACES: default
Referer: http://localhost:13000
Content-Type: application/json

环境变量

以下命令假设服务部署在 http://localhost:13000,实际使用时请替换为您的域名:

export BASE_URL="http://localhost:13000"

创建或更新角色并配置权限

使用 yiask_roles:updateOrCreateWithPermissions API,一次调用即可完成角色创建、权限配置、用户绑定和 AI 员工同步:

curl '$BASE_URL/api/yiask_roles:updateOrCreateWithPermissions' \
  -H 'Authorization: Bearer YOUR_TOKEN_HERE' \
  -H 'X-SPACES: default' \
  -H 'Referer: http://localhost:13000' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "name": "storeOwner",
    "title": "店长",
    "yiaskActions": ["view"],
    "permissions": {
      "dim_prods_default": {
        "rowPermissions": {
          "$and": [
            {
              "产品类型": {
                "$eq": "电子产品"
              }
            }
          ]
        },
        "columnPermissions": {}
      }
    },
    "metricPermissions": [
      {
        "code": "sales_amount",
        "hasPermission": true
      },
      {
        "code": "profit_rate",
        "hasPermission": false
      }
    ],
    "users": [
      {
        "username": "zhangsan",
        "nickname": "张三",
        "email": "zhangsan@example.com",
        "phone": "13800138001",
        "position": "店长",
        "spaces": ["default"],
        "password": "Password123!"
      },
      {
        "username": "lisi",
        "nickname": "李四",
        "email": "aaa@example.com",
        "phone": "13800138002",
        "position": "招商主管",
        "spaces": ["default", "north"],
        "password": "Password123!",
        "permissions": {
          "dim_prods_default": {
            "rowPermissions": {
              "$and": [
                {
                  "产品名称": {
                    "$eq": "笔记本电脑1"
                  }
                }
              ]
            },
            "columnPermissions": {}
          }
        },
        "metricPermissions": [
          {
            "code": "sales_amount",
            "hasPermission": true
          }
        ]
      }
    ],
    "aiEmployees": [
      {
        "username": "sage",
        "defaultEnabled": true
      },
      {
        "username": "nora",
        "defaultEnabled": false
      }
    ]
  }'

参数说明

必填参数

参数类型说明
namestring角色名称(唯一标识)
permissionsobject权限配置对象

可选参数

参数类型默认值说明
titlestringname角色显示名称
yiaskActionsstring[]不传是否显式覆盖 yiask 数据源的通用权限。传 ["view"] 表示保留 yiask 通用查看权限;传 [] 表示移除 yiask 通用查看权限
metricPermissionsarray不传角色级指标权限配置。按指标 code 配置可见性,服务端会将其合并到对应 schema 的 columnPermissions.view
usersarray不传用户全量列表。显式传入时会按该数组全量覆盖当前 role 的用户关联;传 [] 表示清空;不传则保持现有关联不变
aiEmployeesarray不传角色可用 AI 员工全量列表。显式传入时会按该数组全量覆盖当前 role 的 AI 员工关联;传 [] 表示清空;不传则保持现有关联不变

yiaskActions 用法

yiaskActions 用于控制角色在 yiask 数据源级别 的通用权限。

  • ["view"]:允许该角色具备 yiask 通用查看权限
  • []:移除该角色的 yiask 通用查看权限
  • 不传:不主动修改当前角色的 yiask 通用权限配置

例如,只保留单表权限、不保留 yiask 通用查看权限时,可以这样传:

{
  "name": "storeOwner",
  "yiaskActions": [],
  "permissions": {
    "dim_prods_default": {
      "columnPermissions": {
        "view": null
      }
    }
  }
}

permissions 格式

{
  permissions: {
    "[schemaSid]": {
      // 行权限:数据过滤条件
      rowPermissions: {
        "$and": [
          {
            "字段名": { "操作符": "值" }
          }
        ]
      },
      // 列权限:每个 action 可访问的字段列表
      columnPermissions: {
        "[actionName]": ["字段1", "字段2"],  // 只能访问指定字段
        "[actionName]": null                   // null 表示允许访问所有字段
      }
    }
  }
}

users 格式

{
  users: [
    {
      username: "string",      // 必填,用户名(唯一标识)
      nickname: "string",      // 可选,显示名称
      email: "string",         // 可选,邮箱
      phone: "string",         // 可选,手机号
      position: "string",      // 可选,岗位
      spaces: ["string"],      // 可选,用户所属空间列表。显式传入时会同步到 spacesUsers,只确保加入这些空间,不会移除用户原有的其他空间关联
      password: "string",      // 可选,密码。仅创建新用户时生效,更新已有用户时不会覆盖密码
      permissions: {           // 可选,用户级权限覆盖,格式与顶层 permissions 相同
        "[schemaSid]": {
          rowPermissions: {},
          columnPermissions: {}
        }
      },
      metricPermissions: [     // 可选,用户级指标权限覆盖
        {
          code: "string",
          hasPermission: true
        }
      ]
    }
  ]
}

aiEmployees 格式

{
  aiEmployees: [
    {
      username: "string",         // 必填,AI 员工唯一标识,对应 aiEmployees.username
      defaultEnabled: true        // 可选,是否作为该 role 的默认开启 AI 员工,默认 false
    }
  ]
}
  • aiEmployees 显式传入时,服务端会将其视为当前 role 的 全量 AI 员工列表
  • 服务端会同步写入 rolesAiEmployees
  • 如果传入空数组 [],表示清空当前 role 的 AI 员工配置。
  • 如果不传,则保持当前 role 的 AI 员工配置不变。

defaultEnabled 的行为

aiEmployees[].defaultEnabled = true 时,服务端会:

  1. 将该 AI 员工加入当前 role 的可用 AI 员工列表
  2. 将该角色上的 rolesAiEmployees.defaultEnabled 设为 true
  3. 为本次请求中绑定到该 role 的用户补齐 yiask_user_ai_employees.enabled = true 记录

如果对应用户已经存在该 AI 员工记录,则会更新为启用状态,不会重复创建。

例如:

{
  "name": "storeOwner",
  "aiEmployees": [
    {
      "username": "sage",
      "defaultEnabled": true
    },
    {
      "username": "nora",
      "defaultEnabled": false
    }
  ]
}

以上配置表示:

  • sage 对当前角色可用,且默认开启
  • nora 对当前角色可用,但不默认开启

metricPermissions 格式

{
  metricPermissions: [
    {
      code: "sales_amount",   // 指标 code
      hasPermission: true     // true 表示允许查看,false 表示移除查看权限
    }
  ]
}
  • metricPermissions 既可出现在请求顶层,也可出现在 users[].metricPermissions 中。
  • 服务端会按当前空间中的指标 code 查找对应字段,查找范围包括 yiask_propertyyiask_custom_metric
  • 找到后会将结果合并到对应 schema 的 columnPermissions.view 中,不会在响应里额外返回独立的 metricPermissions 字段。
  • hasPermission: true 会将该指标字段加入 viewhasPermission: false 会将该指标字段从 view 中移除。
  • 如果某个 code 不存在,接口会返回 404,例如 metricPermissions[0].code "missing_metric" not found

例如,为角色补充指标可见范围:

{
  "permissions": {
    "dwd_sales_detail_default": {
      "columnPermissions": {
        "view": ["店铺ID"]
      }
    }
  },
  "metricPermissions": [
    {
      "code": "sales_amount",
      "hasPermission": true
    },
    {
      "code": "profit_rate",
      "hasPermission": false
    }
  ]
}

以上配置会把 sales_amount 对应的指标字段加入 dwd_sales_detail_default.columnPermissions.view;如果 profit_rate 已在 view 中,则会被移除。

说明:如果某个 schema 的 columnPermissions.viewnull,再传 metricPermissions 后,最终会改写为仅包含 hasPermission = true 的指标字段列表,而不是继续表示“可查看全部字段”。

幂等语义

  • permissions 会按本次请求整体重建,适合直接传最新完整配置。
  • metricPermissions 会按指标 code 解析并并入角色级 permissions[*].columnPermissions.view
  • users 显式传入时,会被视为当前 role 的全量用户列表。服务端会先清空该 role 现有的用户关联和相关 usersYiaskCollections 记录,再按数组内容重建。
  • users: [] 表示清空当前 role 的所有用户关联。
  • users 不传表示只更新角色和权限,不修改 users 与 role 的关联。
  • users[].spaces 显式传入时,会确保用户加入这些空间,并同步到 spacesUsers;不会删除该用户已有但未声明的其他空间关联。
  • users[].spaces 中的空间必须已存在;如果传入不存在的空间名,接口会返回 400
  • users[].permissions 会写入当前空间对应的 usersYiaskPermissions 记录,用于用户级权限覆盖。
  • users[].metricPermissions 会按相同方式写入当前空间对应的 usersYiaskPermissions,用于用户级指标权限覆盖。
  • 同一张表上,用户级 permissions 会覆盖角色级 permissions;未配置用户级覆盖的表,仍然继承角色权限。
  • users[].password 仅在创建新用户时生效;如果用户已存在,本接口不会覆盖其密码。

说明users[].spaces 用于配置用户所属空间;users[].permissionsusers[].metricPermissions 仍然只会写入当前请求头 X-SPACES 指定的空间。

字段名自动转换

建议使用属性的名称(如 产品类型),同时也支持属性的 ID(如 productTypeproductName),输入属性的 ID 会自动转换为属性名称。

{
  "permissions": {
    "dim_prods_default": {
      "rowPermissions": {
        "$and": [
          {
            "productType": { "$eq": "电子产品" }  // 属性 ID → 自动转换为 "产品类型"
          }
        ]
      },
      "columnPermissions": {
        "view": ["productName", "productType"]  // → ["产品名称", "产品类型"]
      }
    }
  }
}

说明:以上示例中,假设「产品名称」的属性 ID 为 productName,「产品类型」的属性 ID 为 productType

转换规则:

  • 如果字段是某个 property 的 name(如 产品类型),直接保留
  • 如果字段是某个 property 的 id(如 productType),自动转换为 name
  • 如果字段既不是 name 也不是 id(如 $and$eq 等操作符),保留原样

创建或更新单个用户并配置权限

使用 yiask_users:updateOrCreateWithPermissions API,可以在一次调用中创建或更新一个用户,并同步该用户在当前空间的行列权限、指标权限、所属空间和认证器身份:

curl '$BASE_URL/api/yiask_users:updateOrCreateWithPermissions' \
  -H 'Authorization: Bearer YOUR_TOKEN_HERE' \
  -H 'X-SPACES: default' \
  -H 'Referer: http://localhost:13000' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "username": "lisi",
    "nickname": "李四",
    "email": "lisi@example.com",
    "phone": "13800138002",
    "position": "招商主管",
    "password": "Password123!",
    "spaces": ["default", "north"],
    "authenticators": [
      {
        "authenticator": "feishu-main",
        "uuid": "ou_1234567890"
      },
      {
        "authenticator": "wecom-main",
        "uuid": "wecom_1234567890"
      }
    ],
    "permissions": {
      "dim_prods_default": {
        "rowPermissions": {
          "$and": [
            {
              "产品名称": {
                "$eq": "笔记本电脑1"
              }
            }
          ]
        },
        "columnPermissions": {
          "view": ["订单ID"]
        }
      }
    },
    "metricPermissions": [
      {
        "code": "sales_amount",
        "hasPermission": true
      }
    ]
  }'

参数说明

参数类型是否必填说明
usernamestring用户名,作为创建或更新用户的标识
nicknamestring用户昵称
emailstring用户邮箱
phonestring用户手机号
positionstring用户岗位
passwordstring用户密码,仅在创建新用户时写入
spacesstring[]用户需要加入的空间列表。只确保加入这些空间,不会移除已有的其他空间关联
authenticatorsarray认证器绑定列表,用于建立 usersAuthenticators 映射
permissionsobject当前空间的用户级行列权限,key 为 schema sid
metricPermissionsarray当前空间的用户级指标权限,按指标 code 配置可见性

authenticators 格式

{
  authenticators: [
    {
      authenticator: "feishu-main", // 必填,对应 authenticators.name
      uuid: "ou_1234567890"         // 必填,用户在该认证器中的唯一标识
    }
  ]
}

同步认证器时需注意:

  • 每项的 authenticatoruuid 必须同时提交。
  • 同一个认证器在一次请求中只能出现一次。
  • 重复提交相同映射时保持幂等,不会重复创建。
  • 同一用户在同一认证器下提交新的 UUID 时,会更新旧映射。
  • 如果 UUID 已经绑定到其他用户,接口返回 409,整次同步失败并回滚。

预先建立映射后,即使用户尚未通过第三方登录,飞书、企业微信等消息通知渠道也可以通过认证器身份识别该用户。

用户级权限写入规则

  • permissionsmetricPermissions 都写入请求头 X-SPACES 指定空间的 usersYiaskPermissions
  • permissions 的 key 是 schema sid;rowPermissions 使用本文后续介绍的 MongoDB 风格过滤结构。
  • columnPermissions.view 为字段名数组时,只允许查看指定字段;为 null 时表示可以查看全部字段。
  • metricPermissions 会合并到 permissions[*].columnPermissions.view,响应不会额外返回独立的 metricPermissions 字段。
  • spaces 显式传入时会同步写入 spacesUsers,但只增加请求中指定的空间,不移除用户已有的其他空间关联。
  • password 仅在创建新用户时写入,更新已有用户不会覆盖密码。

接口边界:此接口不会绑定角色,也不会写入 usersYiaskCollections。需要同时同步角色绑定或 dataRowScope 时,请改用 yiask_roles:updateOrCreateWithPermissions

返回结果

成功时接口返回用户基础信息以及最终写入的用户级权限:

{
  "id": 12,
  "username": "lisi",
  "nickname": "李四",
  "permissions": {
    "dim_prods_default": {
      "rowPermissions": {
        "$and": [
          {
            "产品名称": {
              "$eq": "笔记本电脑1"
            }
          }
        ]
      },
      "columnPermissions": {
        "view": ["订单ID", "销售额"]
      }
    }
  }
}

常见错误:

HTTP 状态码场景示例
400缺少必填参数或参数格式错误username is required
409当前认证器下的 UUID 已绑定到其他用户uuid "ou_1234567890" is already bound to another user for authenticator "feishu-main"

数据范围语法说明

数据范围(rowPermissions)使用类似 MongoDB 的查询语法来定义数据过滤条件。

逻辑操作符

操作符说明示例
$and逻辑与,所有条件都必须满足见下方示例
$or逻辑或,满足任一条件即可见下方示例

$and 示例(同时满足多个条件):

{
  "rowPermissions": {
    "$and": [
      { "status": { "$eq": "active" } },
      { "age": { "$gte": 18 } }
    ]
  }
}

$or 示例(满足任一条件即可):

{
  "rowPermissions": {
    "$or": [
      { "status": { "$eq": "active" } },
      { "role": { "$eq": "admin" } }
    ]
  }
}

比较操作符

操作符说明示例
$eq等于{ "status": { "$eq": "active" } }
$ne不等于{ "status": { "$ne": "deleted" } }
$gt大于{ "age": { "$gt": 18 } }
$gte大于等于{ "age": { "$gte": 18 } }
$lt小于{ "age": { "$lt": 65 } }
$lte小于等于{ "age": { "$lte": 65 } }
$in包含在数组中{ "status": { "$in": ["active", "pending"] } }
$nin不包含在数组中{ "status": { "$nin": ["deleted", "banned"] } }

字符串操作符

操作符说明示例
$includes包含指定字符串(模糊匹配){ "name": { "$includes": "张三" } }
$notIncludes不包含指定字符串{ "name": { "$notIncludes": "测试" } }
$startsWith以指定字符串开头{ "username": { "$startsWith": "user_" } }
$notStartsWith不以指定字符串开头{ "username": { "$notStartsWith": "admin_" } }
$endWith以指定字符串结尾{ "email": { "$endWith": "@example.com" } }
$notEndWith不以指定字符串结尾{ "email": { "$notEndWith": "@spam.com" } }

数组操作符

操作符说明示例
$anyOf数组包含任一指定元素{ "tags": { "$anyOf": ["urgent", "important"] } }
$noneOf数组不包含任何指定元素{ "tags": { "$noneOf": ["spam", "test"] } }
$match数组完全匹配{ "permissions": { "$match": ["read", "write"] } }
$notMatch数组不完全匹配{ "permissions": { "$notMatch": ["admin"] } }
$arrayEmpty数组为空{ "tags": { "$arrayEmpty": true } }
$arrayNotEmpty数组不为空{ "tags": { "$arrayNotEmpty": true } }

日期操作符

操作符说明示例
$dateOn日期等于某天{ "createdAt": { "$dateOn": "2024-01-01" } }
$dateNotOn日期不等于某天{ "createdAt": { "$dateNotOn": "2024-01-01" } }
$dateBefore日期在指定日期之前{ "createdAt": { "$dateBefore": "2024-01-01" } }
$dateNotBefore日期不在指定日期之前(≥){ "createdAt": { "$dateNotBefore": "2024-01-01" } }
$dateAfter日期在指定日期之后{ "createdAt": { "$dateAfter": "2024-01-01" } }
$dateNotAfter日期不在指定日期之后(≤){ "createdAt": { "$dateNotAfter": "2024-01-01" } }
$dateBetween日期在两个日期之间{ "createdAt": { "$dateBetween": ["2024-01-01", "2024-12-31"] } }

空值/布尔操作符

操作符说明示例
$empty为空(null、undefined、空字符串或空数组){ "phone": { "$empty": true } }
$notEmpty不为空{ "phone": { "$notEmpty": true } }
$isFalsy为假值{ "deleted": { "$isFalsy": true } }
$isTruly为真值{ "verified": { "$isTruly": true } }

用户级权限覆盖

如果某个用户需要比角色更细粒度的权限,可以使用以下任一方式:

  • 调用 yiask_users:updateOrCreateWithPermissions,在顶层 permissionsmetricPermissions 中配置。适合维护单个用户,且不需要变更角色绑定的场景。
  • 调用 yiask_roles:updateOrCreateWithPermissions,在 users[].permissionsusers[].metricPermissions 中配置。适合同时创建或更新角色并绑定用户的场景。

例如,角色默认可以查看所有「电子产品」,但李四只能查看「笔记本电脑1」:

{
  "username": "lisi",
  "permissions": {
    "dim_prods_default": {
      "rowPermissions": {
        "$and": [
          {
            "产品名称": {
              "$eq": "笔记本电脑1"
            }
          }
        ]
      },
      "columnPermissions": {
        "view": null
      }
    }
  }
}

如果还需要单独控制李四的指标可见性,可以在同一次用户级请求中追加 metricPermissions

{
  "username": "lisi",
  "metricPermissions": [
    {
      "code": "sales_amount",
      "hasPermission": true
    }
  ]
}

这会将 sales_amount 对应的指标字段写入李四在当前空间的 usersYiaskPermissions.permissions[*].columnPermissions.view 中。

如果还要在同一次请求中把李四绑定到「店长」角色,则应改用角色级接口:

{
  "name": "storeOwner",
  "permissions": {
    "dim_prods_default": {
      "rowPermissions": {
        "$and": [
          {
            "产品类型": {
              "$eq": "电子产品"
            }
          }
        ]
      }
    }
  },
  "users": [
    {
      "username": "lisi",
      "permissions": {
        "dim_prods_default": {
          "rowPermissions": {
            "$and": [
              {
                "产品名称": {
                  "$eq": "笔记本电脑1"
                }
              }
            ]
          },
          "columnPermissions": {
            "view": null
          }
        }
      }
    }
  ]
}

说明:用户级 permissions 的格式与角色级 permissions 完全一致,但作用范围仅限当前用户、当前空间。

用户所属空间同步

如果需要同步用户所属空间,可以在用户级接口的 spaces 中传入空间列表;使用角色级接口时,则在 users[].spaces 中传入。

例如,使用用户级接口将李四加入 defaultnorth

{
  "username": "lisi",
  "spaces": ["default", "north"]
}

使用角色级接口批量同步时,将张三加入 default,将李四同时加入 defaultnorth

{
  "users": [
    {
      "username": "zhangsan",
      "spaces": ["default"]
    },
    {
      "username": "lisi",
      "spaces": ["default", "north"]
    }
  ]
}
  • 用户级接口的 spaces 和角色级接口的 users[].spaces 都会写入 spacesUsers
  • 显式传入时只会确保用户加入这些空间
  • 不会移除用户已有但未声明的其他空间
  • 如果空间名不存在,接口会返回 400

角色级完整示例

创建「店长」角色,配置商品表权限和指标可见范围,同时创建两位用户,其中李四带有用户级权限覆盖:

curl '$BASE_URL/api/yiask_roles:updateOrCreateWithPermissions' \
  -H 'Authorization: Bearer YOUR_TOKEN_HERE' \
  -H 'X-SPACES: default' \
  -H 'Referer: http://localhost:13000' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "name": "storeOwner",
    "title": "店长",
    "yiaskActions": ["view"],
    "permissions": {
      "dim_prods_default": {
        "rowPermissions": {
          "$and": [
            {
              "产品类型": {
                "$eq": "电子产品"
              }
            }
          ]
        },
        "columnPermissions": {}
      }
    },
    "metricPermissions": [
      {
        "code": "sales_amount",
        "hasPermission": true
      },
      {
        "code": "profit_rate",
        "hasPermission": false
      }
    ],
    "users": [
      {
        "username": "zhangsan",
        "nickname": "张三",
        "email": "zhangsan@example.com",
        "phone": "13800138001",
        "position": "店长",
        "spaces": ["default"],
        "password": "Password123!"
      },
      {
        "username": "lisi",
        "nickname": "李四",
        "email": "aaa@example.com",
        "phone": "13800138001111",
        "position": "招商主管",
        "spaces": ["default", "north"],
        "password": "Password123!",
        "permissions": {
          "dim_prods_default": {
            "rowPermissions": {
              "$and": [
                {
                  "产品名称": {
                    "$eq": "笔记本电脑1"
                  }
                }
              ]
            },
            "columnPermissions": {}
          }
        },
        "metricPermissions": [
          {
            "code": "sales_amount",
            "hasPermission": true
          }
        ]
      }
    ]
  }'

返回结果:

{
  "name": "storeOwner",
  "title": "店长",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-01T00:00:00.000Z",
  "id": 123456789,
  "permissions": {
    "dim_prods_default": {
      "rowPermissions": {
        "$and": [
          {
            "产品类型": {
              "$eq": "电子产品"
            }
          }
        ]
      },
      "columnPermissions": {
        "view": ["销售额"]
      }
    }
  }
}

执行结果

调用成功后:

  1. 创建了「店长」角色
  2. 自动配置了 dim_prods_default 的角色权限
  3. 创建或更新了张三、李四两位用户,并绑定到「店长」角色
  4. users[].spaces 同步到 spacesUsers,确保张三属于 default,李四属于 defaultnorth
  5. 如果用户不存在,会按请求中的 password 创建用户;如果用户已存在,不会覆盖其密码
  6. 将顶层 metricPermissions 按指标 code 解析后合并到角色权限的 columnPermissions.view
  7. users[].permissionsusers[].metricPermissions 同步到 usersYiaskPermissions
  8. 张三继承角色权限,可查看「产品类型 = 电子产品」的数据,并拥有 sales_amount 对应指标字段的查看权限
  9. 李四在 dim_prods_default 上使用用户级权限覆盖,只能查看「产品名称 = 笔记本电脑1」的数据,并额外写入自己的指标可见性配置