@blueking/bk-user-selector 0.0.1-beta.2 → 0.0.2-9.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1,199 @@
1
- ### 人员选择器
1
+ # 蓝鲸多租户人员选择器组件
2
+
3
+ [![npm version](https://badge.fury.io/js/%40blueking%2Fbk-user-selector.svg)](https://badge.fury.io/js/%40blueking%2Fbk-user-selector)
4
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ 蓝鲸多租户人员选择器(BkUserSelector)是一个用于在蓝鲸系统中选择用户的组件,支持单选和多选模式,具备搜索、跨租户查询等功能。
7
+
8
+ ## 特性
9
+
10
+ - 支持 Vue2 和 Vue3 双版本
11
+ - 支持单选和多选模式
12
+ - 支持用户搜索功能
13
+ - 支持跨租户显示
14
+ - 支持拖拽排序(多选模式)
15
+ - 支持快速选择当前用户
16
+ - 支持用户组显示
17
+
18
+ ## 安装
19
+
20
+ ```bash
21
+ npm install @blueking/bk-user-selector
22
+ ```
23
+
24
+ ## 使用方法
25
+
26
+ ### 在 Vue3 中使用
27
+
28
+ ```javascript
29
+ import BkUserSelector from '@blueking/bk-user-selector';
30
+ import '@blueking/bk-user-selector/vue3/vue3.css';
31
+
32
+ export default {
33
+ components: {
34
+ BkUserSelector,
35
+ },
36
+ };
37
+ ```
38
+
39
+ ### 在 Vue2 中使用
40
+
41
+ ```javascript
42
+ import BkUserSelector from '@blueking/bk-user-selector/vue2';
43
+ import '@blueking/bk-user-selector/vue2/vue2.css';
44
+
45
+ export default {
46
+ components: {
47
+ BkUserSelector,
48
+ },
49
+ };
50
+ ```
51
+
52
+ ### 基本用法
53
+
54
+ ```vue
55
+ <template>
56
+ <!-- 单选模式 -->
57
+ <BkUserSelector
58
+ v-model="selectedUser"
59
+ :api-base-url="apiBaseUrl"
60
+ :tenant-id="tenantId"
61
+ :current-user-id="currentUserId"
62
+ :exact-search-key="exactSearchKey"
63
+ @change="handleUserChange"
64
+ />
65
+
66
+ <!-- 多选模式 -->
67
+ <BkUserSelector
68
+ v-model="selectedUsers"
69
+ :api-base-url="apiBaseUrl"
70
+ :tenant-id="tenantId"
71
+ :current-user-id="currentUserId"
72
+ :exact-search-key="exactSearchKey"
73
+ :multiple="true"
74
+ :draggable="true"
75
+ :user-group="userGroup"
76
+ :user-group-name="userGroupName"
77
+ @change="handleUsersChange"
78
+ />
79
+ </template>
80
+
81
+ <script setup>
82
+ import { ref } from 'vue';
83
+
84
+ // API 基础路径
85
+ const apiBaseUrl = ref('https://api.example.com');
86
+ // 租户 ID
87
+ const tenantId = ref('default');
88
+ // 当前用户ID
89
+ const currentUserId = ref('admin');
90
+ // 精确查找key
91
+ const exactSearchKey = ref('bk_username');
92
+ // 单选选中值
93
+ const selectedUser = ref('');
94
+ // 多选选中值
95
+ const selectedUsers = ref([]);
96
+ // 用户组, hidden 为 true 时,不会展示在下拉列表里,但回显时会展示
97
+ const userGroup = ref([
98
+ {
99
+ id: '1',
100
+ name: '运维人员',
101
+ hidden: true,
102
+ },
103
+ {
104
+ id: '2',
105
+ name: '产品人员',
106
+ },
107
+ ]);
108
+ // 用户组名称
109
+ const userGroupName = ref('角色');
110
+
111
+ // 处理单选模式下的值变化
112
+ const handleUserChange = user => {
113
+ console.log('Selected user:', user);
114
+ };
115
+
116
+ // 处理多选模式下的值变化
117
+ const handleUsersChange = users => {
118
+ console.log('Selected users:', users);
119
+ };
120
+ </script>
121
+ ```
122
+
123
+ ## API
124
+
125
+ ### 属性
126
+
127
+ | 参数 | 说明 | 类型 | 默认值 |
128
+ | -------------------- | ----------------------------------------------------------------------- | ------------------------------ | ------------------ |
129
+ | modelValue / v-model | 绑定值,单选为字符串,多选为数组 | String / Array | '' / [] |
130
+ | apiBaseUrl | API 基础 URL | String | '' |
131
+ | tenantId | 租户 ID | String | '' |
132
+ | label | 文本标签 | String | 人员选择 |
133
+ | placeholder | 占位文本 | String | 请输入人员名称搜索 |
134
+ | multiple | 是否多选 | Boolean | false |
135
+ | draggable | 是否可拖拽(仅多选模式有效) | Boolean | false |
136
+ | exactSearchKey | 精确查找key,可选值为 bk_username、login_name、full_name, 多个以逗号分隔 | String | bk_username |
137
+ | currentUserId | 当前用户ID(用于快速选择"我") | String | '' |
138
+ | userGroup | 用户组列表,用于在下拉列表中显示用户组 | Array | [] |
139
+ | userGroupName | 用户组名称,用于在下拉列表中显示用户组名称 | String | 用户群组 |
140
+ | emptyText | 无匹配人员时的提示文本 | String | 无匹配人员 |
141
+ | disabled | 是否禁用 | Boolean | false |
142
+ | renderTag | 渲染标签 | Function(h, userInfo) => VNode | - |
143
+ | renderListItem | 渲染列表项 | Function(h, userInfo) => VNode | - |
144
+ | excludeUserIds | 排除的用户ID列表 | Array | [] |
145
+
146
+ ### 事件
147
+
148
+ | 事件名称 | 说明 | 回调参数 |
149
+ | ----------------- | ---------------- | ---------------- |
150
+ | update:modelValue | 绑定值变化时触发 | 变化后的值 |
151
+ | change | 选中值变化时触发 | 变化后的用户信息 |
152
+
153
+ ## 功能说明
154
+
155
+ ### 快速选择"我"
156
+
157
+ 当设置了`currentUserId`属性后,组件会在输入框右侧显示一个"我"的标签。点击该标签可以快速选择当前用户,无需手动搜索。
158
+
159
+ - 在单选模式下,点击"我"会直接选中当前用户
160
+ - 在多选模式下,点击"我"会将当前用户添加到已选列表中(如果尚未选择)
161
+ - 当当前用户已被选中时,"我"标签会显示为灰色且不可点击
162
+
163
+ ### 用户组显示
164
+
165
+ 当设置了`userGroup`属性后,组件会在下拉列表中显示用户组信息。用户组数据格式如下:
166
+
167
+ ```javascript
168
+ const userGroup = [
169
+ {
170
+ id: '1',
171
+ name: '运维人员',
172
+ },
173
+ {
174
+ id: '2',
175
+ name: '产品人员',
176
+ },
177
+ ];
178
+ ```
179
+
180
+ - 用户组会显示在下拉列表的"用户群组"分组中
181
+ - 用户组数据会展示在最前面
182
+ - 有用户组信息,focus 时就会展示下拉框
183
+
184
+ ## 开发
185
+
186
+ ```bash
187
+ # 安装依赖
188
+ npm install
189
+
190
+ # 开发模式
191
+ npm run dev
192
+
193
+ # 构建
194
+ npm run build
195
+ ```
196
+
197
+ ## 许可证
198
+
199
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blueking/bk-user-selector",
3
- "version": "0.0.1-beta.2",
3
+ "version": "0.0.29.beta.1",
4
4
  "description": "蓝鲸用户选择器",
5
5
  "license": "MIT",
6
6
  "author": "Tencent BlueKing",
@@ -61,13 +61,9 @@
61
61
  "sortablejs": "^1.15.6"
62
62
  },
63
63
  "peerDependencies": {
64
- "@blueking/bkui-library": "^0.0.0-beta.4",
65
- "vue": "^3"
64
+ "@blueking/bkui-library": "^0.0.0-beta.4"
66
65
  },
67
66
  "engines": {
68
67
  "node": ">=18.16.0"
69
- },
70
- "devDependencies": {
71
- "vite": "^6.2.2"
72
68
  }
73
69
  }
@@ -0,0 +1,55 @@
1
+ import { type User, type Tenant, type FormattedUser } from '../types';
2
+ /**
3
+ * 获取本租户所有数据来源的租户信息
4
+ * @param apiBaseUrl - API基础URL
5
+ * @param tenantId - 租户ID
6
+ * @returns 租户列表Promise
7
+ */
8
+ export declare const getTenants: (apiBaseUrl: string, tenantId: string) => Promise<Tenant[]>;
9
+ /**
10
+ * 模糊搜索用户
11
+ * @param apiBaseUrl - API基础URL
12
+ * @param tenantId - 租户ID
13
+ * @param keyword - 搜索关键词
14
+ * @returns 用户列表Promise
15
+ */
16
+ export declare const searchUsers: (params: {
17
+ apiBaseUrl: string;
18
+ tenantId: string;
19
+ keyword: string;
20
+ enableMultiTenantMode?: boolean;
21
+ }) => Promise<User[]>;
22
+ /**
23
+ * 批量精准查找用户
24
+ * @param apiBaseUrl - API基础URL
25
+ * @param tenantId - 租户ID
26
+ * @param users - 用户名列表
27
+ * @param exactSearchKey - 精确查找key
28
+ * @returns 查找到的用户列表Promise
29
+ */
30
+ export declare const lookupUsers: (params: {
31
+ apiBaseUrl: string;
32
+ tenantId: string;
33
+ exactSearchKey: string;
34
+ usersList: string[];
35
+ enableMultiTenantMode?: boolean;
36
+ }) => Promise<User[]>;
37
+ /**
38
+ * 将API返回的用户数据格式化为组件所需格式
39
+ * @param users - API返回的用户列表
40
+ * @returns 格式化后的用户列表
41
+ */
42
+ export declare const formatUsers: (users: User[]) => FormattedUser[];
43
+ /**
44
+ * 获取用户列表 兼容旧版本的人员选择器
45
+ * @param url 请求的 URL
46
+ * @param params 请求参数
47
+ * @returns 用户列表
48
+ */
49
+ export declare const getUserList: (url: string, params: {
50
+ userIds?: string[];
51
+ keyword?: string;
52
+ pageSize?: number;
53
+ page?: number;
54
+ appCode?: string;
55
+ }) => Promise<User[]>;
@@ -0,0 +1,39 @@
1
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ /**
3
+ * 当前用户ID
4
+ */
5
+ currentUserId: {
6
+ type: StringConstructor;
7
+ default: string;
8
+ };
9
+ /**
10
+ * 是否禁用
11
+ */
12
+ isDisabled: {
13
+ type: BooleanConstructor;
14
+ default: boolean;
15
+ };
16
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
17
+ click: (...args: any[]) => void;
18
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
19
+ /**
20
+ * 当前用户ID
21
+ */
22
+ currentUserId: {
23
+ type: StringConstructor;
24
+ default: string;
25
+ };
26
+ /**
27
+ * 是否禁用
28
+ */
29
+ isDisabled: {
30
+ type: BooleanConstructor;
31
+ default: boolean;
32
+ };
33
+ }>> & Readonly<{
34
+ onClick?: ((...args: any[]) => any) | undefined;
35
+ }>, {
36
+ currentUserId: string;
37
+ isDisabled: boolean;
38
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
39
+ export default _default;
@@ -0,0 +1,33 @@
1
+ import { FormattedUser, MultipleSelectorProps } from '../types';
2
+ declare const _default: import("vue").DefineComponent<MultipleSelectorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ "update:selectedUsers": (...args: any[]) => void;
4
+ "add-user": (...args: any[]) => void;
5
+ "remove-user": (...args: any[]) => void;
6
+ }, string, import("vue").PublicProps, Readonly<MultipleSelectorProps> & Readonly<{
7
+ "onUpdate:selectedUsers"?: ((...args: any[]) => any) | undefined;
8
+ "onAdd-user"?: ((...args: any[]) => any) | undefined;
9
+ "onRemove-user"?: ((...args: any[]) => any) | undefined;
10
+ }>, {
11
+ tenantId: string;
12
+ apiBaseUrl: string;
13
+ exactSearchKey: string;
14
+ currentUserId: string;
15
+ tenants: Record<string, string>;
16
+ userGroup: {
17
+ id: string;
18
+ name: string;
19
+ hidden
20
+ /**
21
+ * 多选模式用户选择器组件
22
+ */
23
+ ?: boolean;
24
+ }[];
25
+ userGroupName: string;
26
+ emptyText: string;
27
+ draggable: boolean;
28
+ modelValue: string[];
29
+ selectedUsers: FormattedUser[];
30
+ placeholder: string;
31
+ excludeUserIds: string[];
32
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
+ export default _default;
@@ -0,0 +1,205 @@
1
+ /**
2
+ * 用户选择器下拉菜单组件
3
+ */
4
+ import { createVNode, VNode } from 'vue';
5
+ import { FormattedUser } from '../types';
6
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
7
+ /**
8
+ * 是否显示下拉菜单
9
+ */
10
+ isShow: {
11
+ type: BooleanConstructor;
12
+ default: boolean;
13
+ };
14
+ /**
15
+ * 容器宽度
16
+ */
17
+ containerWidth: {
18
+ type: (StringConstructor | NumberConstructor)[];
19
+ default: string;
20
+ };
21
+ /**
22
+ * popover crossAxis 偏移量
23
+ */
24
+ crossAxisOffset: {
25
+ type: NumberConstructor;
26
+ default: number;
27
+ };
28
+ /**
29
+ * 是否加载中
30
+ */
31
+ loading: {
32
+ type: BooleanConstructor;
33
+ default: boolean;
34
+ };
35
+ /**
36
+ * 搜索结果选项
37
+ */
38
+ options: {
39
+ type: () => FormattedUser[];
40
+ default: () => never[];
41
+ };
42
+ /**
43
+ * 搜索关键词
44
+ */
45
+ searchQuery: {
46
+ type: StringConstructor;
47
+ default: string;
48
+ };
49
+ /**
50
+ * 当前租户ID
51
+ */
52
+ tenantId: {
53
+ type: StringConstructor;
54
+ default: string;
55
+ };
56
+ /**
57
+ * 租户信息映射
58
+ */
59
+ tenants: {
60
+ type: () => Record<string, string>;
61
+ default: () => {};
62
+ };
63
+ /**
64
+ * 用户组
65
+ */
66
+ userGroup: {
67
+ type: () => {
68
+ id: string;
69
+ name: string;
70
+ hidden?: boolean;
71
+ }[];
72
+ default: () => never[];
73
+ };
74
+ /**
75
+ * 用户组名称
76
+ */
77
+ userGroupName: {
78
+ type: StringConstructor;
79
+ default: string;
80
+ };
81
+ /**
82
+ * 无匹配人员时的提示文本
83
+ */
84
+ emptyText: {
85
+ type: StringConstructor;
86
+ default: string;
87
+ };
88
+ /**
89
+ * 渲染列表项
90
+ */
91
+ renderListItem: {
92
+ type: () => (h: typeof createVNode, item: FormattedUser) => VNode;
93
+ };
94
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
95
+ "select-user": (...args: any[]) => void;
96
+ "click-outside": (...args: any[]) => void;
97
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
98
+ /**
99
+ * 是否显示下拉菜单
100
+ */
101
+ isShow: {
102
+ type: BooleanConstructor;
103
+ default: boolean;
104
+ };
105
+ /**
106
+ * 容器宽度
107
+ */
108
+ containerWidth: {
109
+ type: (StringConstructor | NumberConstructor)[];
110
+ default: string;
111
+ };
112
+ /**
113
+ * popover crossAxis 偏移量
114
+ */
115
+ crossAxisOffset: {
116
+ type: NumberConstructor;
117
+ default: number;
118
+ };
119
+ /**
120
+ * 是否加载中
121
+ */
122
+ loading: {
123
+ type: BooleanConstructor;
124
+ default: boolean;
125
+ };
126
+ /**
127
+ * 搜索结果选项
128
+ */
129
+ options: {
130
+ type: () => FormattedUser[];
131
+ default: () => never[];
132
+ };
133
+ /**
134
+ * 搜索关键词
135
+ */
136
+ searchQuery: {
137
+ type: StringConstructor;
138
+ default: string;
139
+ };
140
+ /**
141
+ * 当前租户ID
142
+ */
143
+ tenantId: {
144
+ type: StringConstructor;
145
+ default: string;
146
+ };
147
+ /**
148
+ * 租户信息映射
149
+ */
150
+ tenants: {
151
+ type: () => Record<string, string>;
152
+ default: () => {};
153
+ };
154
+ /**
155
+ * 用户组
156
+ */
157
+ userGroup: {
158
+ type: () => {
159
+ id: string;
160
+ name: string;
161
+ hidden?: boolean;
162
+ }[];
163
+ default: () => never[];
164
+ };
165
+ /**
166
+ * 用户组名称
167
+ */
168
+ userGroupName: {
169
+ type: StringConstructor;
170
+ default: string;
171
+ };
172
+ /**
173
+ * 无匹配人员时的提示文本
174
+ */
175
+ emptyText: {
176
+ type: StringConstructor;
177
+ default: string;
178
+ };
179
+ /**
180
+ * 渲染列表项
181
+ */
182
+ renderListItem: {
183
+ type: () => (h: typeof createVNode, item: FormattedUser) => VNode;
184
+ };
185
+ }>> & Readonly<{
186
+ "onSelect-user"?: ((...args: any[]) => any) | undefined;
187
+ "onClick-outside"?: ((...args: any[]) => any) | undefined;
188
+ }>, {
189
+ tenantId: string;
190
+ tenants: Record<string, string>;
191
+ isShow: boolean;
192
+ containerWidth: string | number;
193
+ crossAxisOffset: number;
194
+ loading: boolean;
195
+ options: FormattedUser[];
196
+ searchQuery: string;
197
+ userGroup: {
198
+ id: string;
199
+ name: string;
200
+ hidden?: boolean;
201
+ }[];
202
+ userGroupName: string;
203
+ emptyText: string;
204
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
205
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import { SingleSelectorProps } from '../types';
2
+ declare const _default: import("vue").DefineComponent<SingleSelectorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ change: (...args: any[]) => void;
4
+ "update:modelValue": (...args: any[]) => void;
5
+ }, string, import("vue").PublicProps, Readonly<SingleSelectorProps> & Readonly<{
6
+ onChange?: ((...args: any[]) => any) | undefined;
7
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
8
+ }>, {
9
+ tenantId: string;
10
+ apiBaseUrl: string;
11
+ exactSearchKey: string;
12
+ currentUserId: string;
13
+ userGroup: {
14
+ id: string;
15
+ name: string;
16
+ hidden
17
+ /**
18
+ * 单选模式用户选择器组件
19
+ */
20
+ ?: boolean;
21
+ }[];
22
+ userGroupName: string;
23
+ emptyText: string;
24
+ modelValue: string;
25
+ placeholder: string;
26
+ excludeUserIds: string[];
27
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
+ export default _default;
@@ -0,0 +1,37 @@
1
+ import type { FormattedUser } from '../types';
2
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
3
+ user: {
4
+ type: () => FormattedUser;
5
+ required: true;
6
+ };
7
+ tenantId: {
8
+ type: StringConstructor;
9
+ required: true;
10
+ };
11
+ tenants: {
12
+ type: () => Record<string, string>;
13
+ required: true;
14
+ };
15
+ render: {
16
+ type: FunctionConstructor;
17
+ required: false;
18
+ };
19
+ }>, () => any, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
20
+ user: {
21
+ type: () => FormattedUser;
22
+ required: true;
23
+ };
24
+ tenantId: {
25
+ type: StringConstructor;
26
+ required: true;
27
+ };
28
+ tenants: {
29
+ type: () => Record<string, string>;
30
+ required: true;
31
+ };
32
+ render: {
33
+ type: FunctionConstructor;
34
+ required: false;
35
+ };
36
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
37
+ export default _default;
@@ -0,0 +1,33 @@
1
+ import { UserSelectorProps } from '../types';
2
+ declare const _default: import("vue").DefineComponent<UserSelectorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ change: (...args: any[]) => void;
4
+ "update:modelValue": (...args: any[]) => void;
5
+ }, string, import("vue").PublicProps, Readonly<UserSelectorProps> & Readonly<{
6
+ onChange?: ((...args: any[]) => any) | undefined;
7
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
8
+ }>, {
9
+ tenantId: string;
10
+ apiBaseUrl: string;
11
+ enableMultiTenantMode: boolean;
12
+ exactSearchKey: string;
13
+ currentUserId: string;
14
+ disabled: boolean;
15
+ userGroup: {
16
+ id: string;
17
+ name: string;
18
+ hidden
19
+ /**
20
+ * 蓝鲸用户选择器组件
21
+ * @module components/UserSelector
22
+ */
23
+ ?: boolean;
24
+ }[];
25
+ userGroupName: string;
26
+ emptyText: string;
27
+ draggable: boolean;
28
+ modelValue: string | string[];
29
+ placeholder: string;
30
+ excludeUserIds: string[];
31
+ multiple: boolean;
32
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
+ export default _default;