@blueking/bk-org-selector
v0.1.3
Published
蓝鲸多租户组织架构选择器
Readme
蓝鲸多租户组织选择器
蓝鲸多租户组织选择器是一个用于选择组织架构的 Vue 组件,支持 Vue2 和 Vue3 双版本,适用于蓝鲸智云平台的多租户场景。
✨ 特性
- 🎯 双版本支持 - 同时支持 Vue2 和 Vue3
- 🌲 组织架构树形展示 - 清晰展示多层级组织结构
- 👥 人员选择 - 支持选择普通用户和虚拟账号
- 🏢 多租户支持 - 支持跨租户协同场景
- 🔍 搜索功能 - 支持组织名称、用户名称搜索
- 📋 批量录入 - 支持批量粘贴用户名/虚拟账号名快速添加
- 🌐 国际化 - 内置中英文语言包
- 📝 TypeScript - 完整的类型定义支持
- 🎨 自定义渲染 - 支持自定义空状态和结果展示
📦 安装
npm install @blueking/bk-org-selector
# 或
pnpm add @blueking/bk-org-selector🚀 快速开始
Vue3 版本
<template>
<bk-org-selector
v-model="selectedOrg"
:api-base-url="apiBaseUrl"
:tenant-id="tenantId"
has-user
@change="handleChange"
@confirm="handleConfirm"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import BkOrgSelector from '@blueking/bk-org-selector';
import '@blueking/bk-org-selector/vue3/vue3.css';
import type { TreeItem } from '@blueking/bk-org-selector';
const apiBaseUrl = 'https://your-api-domain.com';
const tenantId = 'your-tenant-id';
const selectedOrg = ref<TreeItem[]>([]);
const handleChange = (value: TreeItem[]) => {
console.log('选中数据变化:', value);
};
const handleConfirm = (result: any) => {
console.log('确认选择:', result);
};
</script>Vue2 版本
<template>
<bk-org-selector
v-model="selectedOrg"
:api-base-url="apiBaseUrl"
:tenant-id="tenantId"
has-user
@change="handleChange"
@confirm="handleConfirm"
>
<bk-button>请选择组织或人员</bk-button>
</bk-org-selector>
</template>
<script>
import BkOrgSelector from '@blueking/bk-org-selector/vue2';
import '@blueking/bk-org-selector/vue2/vue2.css';
export default {
components: {
BkOrgSelector,
},
data() {
return {
apiBaseUrl: 'https://your-api-domain.com',
tenantId: 'your-tenant-id',
selectedOrg: [],
};
},
methods: {
handleChange(value) {
console.log('选中数据变化:', value);
},
handleConfirm(result) {
console.log('确认选择:', result);
},
},
};
</script>批量录入模式
通过 has-batch-input 启用批量录入能力,在弹窗左侧面板顶部显示「组织架构 / 批量录入」Tab 切换,支持通过粘贴用户名或虚拟账号名批量添加。
<template>
<bk-org-selector
v-model="selectedOrg"
:api-base-url="apiBaseUrl"
:tenant-id="tenantId"
has-batch-input
has-user
has-virtual-users
@confirm="handleConfirm"
/>
</template>批量录入特性:
- 支持回车、分号、逗号、空格等多种分隔符
- 自动去除括号中的备注信息(如
zhangsan(张三)→zhangsan) - 通过
login_name字段精确匹配用户 - 解析结果支持全选/单选,勾选后添加到右侧结果预览
- 未匹配的用户名会显示警告提示
- 当前仅支持批量添加用户和虚拟账号,不支持批量添加组织
路径展示模式
通过 display-mode="path" 切换为路径列表展示,适用于展示已选组织/人员的层级路径,如"启用范围"等场景。
<template>
<bk-org-selector
v-model="selectedOrg"
:api-base-url="apiBaseUrl"
:tenant-id="tenantId"
display-mode="path"
display-width="600px"
has-user
@confirm="handleConfirm"
/>
</template>路径模式特性:
- 按类型分组展示(组织、用户、虚拟账号)
- 显示完整组织路径,路径过长时自动截断(保留首段和末段,中间用
...代替) - 跨租户项显示橙色租户标识(如
@嘉为) - hover 时显示删除按钮,支持分组清空
- 宽度支持 prop 配置 + CSS 变量
--org-path-list-width覆盖
📖 API 文档
属性 Props
| 属性名 | 类型 | 默认值 | 必填 | 说明 |
| -------------------- | ------------ | --------------------------- | ---- | ---------------------------------------------------------------------------------------------------- |
| v-model / modelValue | TreeItem[] | [] | 是 | 选中的组织/人员列表,支持双向绑定 |
| apiBaseUrl | string | '' | 是 | 接口基础 URL,所有 API 请求的前缀 |
| apiPrefix | string | '/api/v3/open-web/tenant' | 否 | API 路径前缀,用于拼接具体的 API 端点,完整请求路径为 apiBaseUrl + apiPrefix + endpoint |
| tenantId | string | 'default' | 是 | 租户 ID,用于多租户系统的数据隔离 |
| hasUser | boolean | false | 否 | 是否可选择人员,启用后会在组织树中显示用户节点 |
| hasVirtualUsers | boolean | false | 否 | 是否可选择虚拟账号,启用后会在租户列表中显示虚拟账号选项 |
| readonly | boolean | false | 否 | 是否只读模式,只读时可查看已选中数据但不能编辑 |
| disabled | boolean | false | 否 | 是否禁用整个组件,禁用后所有交互功能不可用 |
| displayMode | string | 'tag' | 否 | 结果展示模式:'simple' 只显示标题,'tag' 标题+标签列表,'path' 标题+路径列表 |
| displayWidth | string | - | 否 | 结果展示区域宽度,支持 CSS 值如 '400px'、'100%',不传时跟随父容器宽度 |
| isSimpleShow | boolean | false | 否 | 是否简单展示模式(已废弃,建议使用 displayMode="simple" 替代) |
| checkStrictly | boolean | false | 否 | 是否严格遵循父子互相关联,false 时父子节点选中状态互不影响 |
| disableCheck | boolean | false | 否 | 是否禁用勾选功能 |
| hasBatchInput | boolean | false | 否 | 是否启用批量录入,启用后弹窗左侧显示「组织架构 / 批量录入」Tab 切换 |
| hasSelectAll | boolean | false | 否 | 是否显示"全部人员"选项,启用后在弹窗底部显示全选复选框 |
| zIndex | number | 自动计算 | 否 | 弹窗层级(z-index) |
| renderEmpty | Function | - | 否 | 空状态自定义渲染函数 |
| renderResult | Function | - | 否 | 结果区域自定义渲染函数 |
| avatarBaseUrl | string | '' | 否 | 头像基础 URL,用于拼接用户头像地址 |
| showHoverPath | boolean | false | 否 | 是否在 hover 树节点时以 Popover 展示组织路径,路径通过接口获取,带缓存 |
| virtualRender | boolean | false | 否 | 是否启用虚拟渲染,启用后树组件使用虚拟滚动,适用于大数据量场景;组件会根据弹窗可用空间自动计算树高度 |
事件 Events
| 事件名 | 回调参数 | 说明 |
| ----------------- | ------------------------ | ------------------------ |
| change | (value: TreeItem[]) | 选择值变化时触发 |
| changeResult | (result: ResultItem[]) | 格式化后的结果变化时触发 |
| confirm | (result: ResultItem[]) | 点击确认按钮时触发 |
| closed | - | 弹窗关闭时触发 |
| update:modelValue | (value: TreeItem[]) | v-model 更新事件 |
方法 Methods
通过 ref 获取组件实例后可调用以下方法:
| 方法名 | 参数 | 说明 |
| ---------------- | ----------------------------------------- | ------------------------ |
| openEdit | - | 打开编辑弹窗 |
| handleDeleteItem | (item: TreeItem, needConfirm?: boolean) | 删除单个选中项 |
| handleDeleteAll | (type: string, needConfirm?: boolean) | 删除指定类型的所有选中项 |
| destroy | - | 销毁组件,清理所有状态 |
<template>
<bk-org-selector
ref="selectorRef"
...
/>
<button @click="openSelector">打开选择器</button>
</template>
<script setup>
import { ref } from 'vue';
const selectorRef = ref();
const openSelector = () => {
selectorRef.value?.openEdit();
};
</script>📋 数据结构
TreeItem
选中项的数据结构:
interface TreeItem {
/** 节点 ID */
id: number | string;
/** 节点名称 */
name?: string;
/** 节点类型:'org' 组织 | 'user' 用户 | 'virtual' 虚拟账号 | 'all' 全部人员 */
type: 'org' | 'user' | 'virtual' | 'all';
/** 所属租户 ID */
owner_tenant_id?: string;
/** 用户名(用户类型专用) */
bk_username?: string;
/** 显示名称 */
display_name?: string;
/** 组织路径 */
organization_path?: string;
/** 是否有子节点 */
has_child?: boolean;
/** 子节点列表 */
children?: TreeItem[];
}ResultItem
格式化后的结果数据结构:
interface ResultItem {
/** 分组名称,如 '组织'、'用户'、'虚拟账号' */
name: string;
/** 分组类型 */
type: 'org' | 'user' | 'virtual' | 'all';
/** 该分组下的数据列表 */
data: Array<{
id: number | string;
name?: string;
owner_tenant_id?: string;
}>;
}🎨 自定义渲染
自定义空状态
<template>
<bk-org-selector
v-model="selectedOrg"
:render-empty="renderEmpty"
...
/>
</template>
<script setup>
import { h } from 'vue';
const renderEmpty = createElement => {
return createElement('div', { class: 'custom-empty' }, [createElement('span', '点击选择组织或人员')]);
};
</script>自定义结果展示
<template>
<bk-org-selector
v-model="selectedOrg"
:render-result="renderResult"
...
/>
</template>
<script setup>
import { h } from 'vue';
const renderResult = (createElement, props) => {
const { result } = props;
return createElement('div', { class: 'custom-result' }, [createElement('span', `已选择 ${result.length} 项`)]);
};
</script>🌐 国际化
组件内置中英文语言包,会自动根据 blueking_language Cookie 值切换语言:
- Cookie 值为
en时使用英文 - 其他情况默认使用中文
支持的文案包括:
- 选择组织、结果预览、确定、取消等操作文案
- 组织、用户、虚拟账号等类型名称
- 搜索提示和空状态文案
📁 目录结构
@blueking/bk-org-selector
├── vue3/ # Vue3 构建产物
│ ├── index.es.min.js
│ └── vue3.css
├── vue2/ # Vue2 构建产物
│ ├── index.es.min.js
│ └── vue2.css
└── typings/ # TypeScript 类型定义
├── vue3.d.ts
└── vue2.d.ts🔧 环境要求
- Node.js: >= 18.16.0
- Vue 3: >= 3.0.0
- Vue 2: >= 2.6.0
🤝 贡献
欢迎提交 Issue 和 Pull Request 来帮助改进这个项目。
📄 许可证
MIT License © Tencent BlueKing
