@blueking/bk-user-selector 0.0.1-beta.2 → 0.0.3

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,149 @@
1
- ### 人员选择器
1
+ # 蓝鲸用户选择器组件
2
+
3
+ 蓝鲸用户选择器(BkUserSelector)是一个用于在蓝鲸系统中选择用户的组件,支持单选和多选模式,具备搜索、跨租户查询等功能。
4
+
5
+ ## 特性
6
+
7
+ - 支持单选和多选模式
8
+ - 支持用户搜索功能
9
+ - 支持跨租户显示
10
+ - 支持拖拽排序(多选模式)
11
+ - 支持快速选择当前用户
12
+
13
+ ## 安装
14
+
15
+ ```bash
16
+ npm install @blueking/bk-user-selector
17
+ ```
18
+
19
+ ## 使用方法
20
+
21
+ ### 在 Vue3 中使用
22
+
23
+ ```javascript
24
+ // 全局注册
25
+ import { createApp } from 'vue';
26
+ import BkUserSelector from '@blueking/bk-user-selector';
27
+ import '@blueking/bk-user-selector/vue3/vue3.css';
28
+
29
+ const app = createApp(App);
30
+ app.use(BkUserSelector);
31
+ app.mount('#app');
32
+
33
+ // 或者局部注册
34
+ import { UserSelector } from '@blueking/bk-user-selector';
35
+
36
+ export default {
37
+ components: {
38
+ BkUserSelector: UserSelector,
39
+ },
40
+ };
41
+ ```
42
+
43
+ ### 在 Vue2 中使用
44
+
45
+ ```javascript
46
+ import BkUserSelector from '@blueking/bk-user-selector/vue2';
47
+ import '@blueking/bk-user-selector/vue2/vue2.css';
48
+ ```
49
+
50
+ ### 基本用法
51
+
52
+ ```vue
53
+ <template>
54
+ <!-- 单选模式 -->
55
+ <BkUserSelector
56
+ v-model="selectedUser"
57
+ :api-base-url="apiBaseUrl"
58
+ :tenant-id="tenantId"
59
+ :current-user-id="currentUserId"
60
+ @change="handleUserChange"
61
+ />
62
+
63
+ <!-- 多选模式 -->
64
+ <BkUserSelector
65
+ v-model="selectedUsers"
66
+ :api-base-url="apiBaseUrl"
67
+ :tenant-id="tenantId"
68
+ :current-user-id="currentUserId"
69
+ :multiple="true"
70
+ :draggable="true"
71
+ @change="handleUsersChange"
72
+ />
73
+ </template>
74
+
75
+ <script setup>
76
+ import { ref } from 'vue';
77
+
78
+ // API 基础路径
79
+ const apiBaseUrl = ref('https://api.example.com');
80
+ // 租户 ID
81
+ const tenantId = ref('default');
82
+ // 当前用户ID
83
+ const currentUserId = ref('admin');
84
+ // 单选选中值
85
+ const selectedUser = ref('');
86
+ // 多选选中值
87
+ const selectedUsers = ref([]);
88
+
89
+ // 处理单选模式下的值变化
90
+ const handleUserChange = user => {
91
+ console.log('Selected user:', user);
92
+ };
93
+
94
+ // 处理多选模式下的值变化
95
+ const handleUsersChange = users => {
96
+ console.log('Selected users:', users);
97
+ };
98
+ </script>
99
+ ```
100
+
101
+ ## API
102
+
103
+ ### 属性
104
+
105
+ | 参数 | 说明 | 类型 | 默认值 |
106
+ | -------------------- | -------------------------------- | -------------- | -------------------- |
107
+ | modelValue / v-model | 绑定值,单选为字符串,多选为数组 | String / Array | '' / [] |
108
+ | label | 文本标签 | String | '人员选择' |
109
+ | required | 是否必填 | Boolean | false |
110
+ | placeholder | 占位文本 | String | '请输入人员名称搜索' |
111
+ | multiple | 是否多选 | Boolean | false |
112
+ | draggable | 是否可拖拽(仅多选模式有效) | Boolean | false |
113
+ | apiBaseUrl | API 基础 URL | String | '' |
114
+ | tenantId | 租户 ID | String | '' |
115
+ | currentUserId | 当前用户ID(用于快速选择"我") | String | '' |
116
+
117
+ ### 事件
118
+
119
+ | 事件名称 | 说明 | 回调参数 |
120
+ | ----------------- | ---------------- | ---------------- |
121
+ | update:modelValue | 绑定值变化时触发 | 变化后的值 |
122
+ | change | 选中值变化时触发 | 变化后的用户信息 |
123
+
124
+ ## 功能说明
125
+
126
+ ### 快速选择"我"
127
+
128
+ 当设置了`currentUserId`属性后,组件会在输入框右侧显示一个"我"的标签。点击该标签可以快速选择当前用户,无需手动搜索。
129
+
130
+ - 在单选模式下,点击"我"会直接选中当前用户
131
+ - 在多选模式下,点击"我"会将当前用户添加到已选列表中(如果尚未选择)
132
+ - 当当前用户已被选中时,"我"标签会显示为灰色且不可点击
133
+
134
+ ## 开发
135
+
136
+ ```bash
137
+ # 安装依赖
138
+ npm install
139
+
140
+ # 开发模式
141
+ npm run dev
142
+
143
+ # 构建
144
+ npm run build
145
+ ```
146
+
147
+ ## 许可证
148
+
149
+ 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.3",
4
4
  "description": "蓝鲸用户选择器",
5
5
  "license": "MIT",
6
6
  "author": "Tencent BlueKing",
@@ -0,0 +1,34 @@
1
+ /**
2
+ * 用户选择器相关API
3
+ * @module api/user
4
+ */
5
+ import { type User, type Tenant, type FormattedUser } from '../types';
6
+ /**
7
+ * 获取本租户所有数据来源的租户信息
8
+ * @param apiBaseUrl - API基础URL
9
+ * @param tenantId - 租户ID
10
+ * @returns 租户列表Promise
11
+ */
12
+ export declare const getTenants: (apiBaseUrl: string, tenantId: string) => Promise<Tenant[]>;
13
+ /**
14
+ * 模糊搜索用户
15
+ * @param apiBaseUrl - API基础URL
16
+ * @param tenantId - 租户ID
17
+ * @param keyword - 搜索关键词
18
+ * @returns 用户列表Promise
19
+ */
20
+ export declare const searchUsers: (apiBaseUrl?: string, tenantId?: string, keyword?: string) => Promise<User[]>;
21
+ /**
22
+ * 批量精准查找用户
23
+ * @param apiBaseUrl - API基础URL
24
+ * @param tenantId - 租户ID
25
+ * @param users - 用户名列表
26
+ * @returns 查找到的用户列表Promise
27
+ */
28
+ export declare const lookupUsers: (apiBaseUrl?: string, tenantId?: string, users?: string[]) => Promise<User[]>;
29
+ /**
30
+ * 将API返回的用户数据格式化为组件所需格式
31
+ * @param users - API返回的用户列表
32
+ * @returns 格式化后的用户列表
33
+ */
34
+ export declare const formatUsers: (users: User[]) => FormattedUser[];
@@ -0,0 +1,134 @@
1
+ import { FormattedUser } from '../types';
2
+ declare const _default: import("vue").DefineComponent<{
3
+ /**
4
+ * 绑定值
5
+ */
6
+ modelValue: {
7
+ type: ArrayConstructor;
8
+ default: () => never[];
9
+ };
10
+ /**
11
+ * 占位文本
12
+ */
13
+ placeholder: {
14
+ type: StringConstructor;
15
+ default: string;
16
+ };
17
+ /**
18
+ * 是否可拖拽
19
+ */
20
+ draggable: {
21
+ type: BooleanConstructor;
22
+ default: boolean;
23
+ };
24
+ /**
25
+ * API 基础 URL
26
+ */
27
+ apiBaseUrl: {
28
+ type: StringConstructor;
29
+ default: string;
30
+ };
31
+ /**
32
+ * 租户 ID
33
+ */
34
+ tenantId: {
35
+ type: StringConstructor;
36
+ default: string;
37
+ };
38
+ /**
39
+ * 已选用户
40
+ */
41
+ selectedUsers: {
42
+ type: () => FormattedUser[];
43
+ default: () => never[];
44
+ };
45
+ /**
46
+ * 租户信息映射
47
+ */
48
+ tenants: {
49
+ type: () => Record<string, string>;
50
+ default: () => {};
51
+ };
52
+ /**
53
+ * 当前用户ID
54
+ */
55
+ currentUserId: {
56
+ type: StringConstructor;
57
+ default: string;
58
+ };
59
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
60
+ "update:selectedUsers": (...args: any[]) => void;
61
+ "add-user": (...args: any[]) => void;
62
+ "remove-user": (...args: any[]) => void;
63
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
64
+ /**
65
+ * 绑定值
66
+ */
67
+ modelValue: {
68
+ type: ArrayConstructor;
69
+ default: () => never[];
70
+ };
71
+ /**
72
+ * 占位文本
73
+ */
74
+ placeholder: {
75
+ type: StringConstructor;
76
+ default: string;
77
+ };
78
+ /**
79
+ * 是否可拖拽
80
+ */
81
+ draggable: {
82
+ type: BooleanConstructor;
83
+ default: boolean;
84
+ };
85
+ /**
86
+ * API 基础 URL
87
+ */
88
+ apiBaseUrl: {
89
+ type: StringConstructor;
90
+ default: string;
91
+ };
92
+ /**
93
+ * 租户 ID
94
+ */
95
+ tenantId: {
96
+ type: StringConstructor;
97
+ default: string;
98
+ };
99
+ /**
100
+ * 已选用户
101
+ */
102
+ selectedUsers: {
103
+ type: () => FormattedUser[];
104
+ default: () => never[];
105
+ };
106
+ /**
107
+ * 租户信息映射
108
+ */
109
+ tenants: {
110
+ type: () => Record<string, string>;
111
+ default: () => {};
112
+ };
113
+ /**
114
+ * 当前用户ID
115
+ */
116
+ currentUserId: {
117
+ type: StringConstructor;
118
+ default: string;
119
+ };
120
+ }>> & {
121
+ "onUpdate:selectedUsers"?: ((...args: any[]) => any) | undefined;
122
+ "onAdd-user"?: ((...args: any[]) => any) | undefined;
123
+ "onRemove-user"?: ((...args: any[]) => any) | undefined;
124
+ }, {
125
+ tenants: Record<string, string>;
126
+ draggable: boolean;
127
+ modelValue: unknown[];
128
+ placeholder: string;
129
+ apiBaseUrl: string;
130
+ tenantId: string;
131
+ selectedUsers: FormattedUser[];
132
+ currentUserId: string;
133
+ }, {}>;
134
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import { SingleSelectorProps } from '../types';
2
+ declare const _default: import("vue").DefineComponent<__VLS_TypePropsToOption<SingleSelectorProps>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ change: (...args: any[]) => void;
4
+ "update:modelValue": (...args: any[]) => void;
5
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToOption<SingleSelectorProps>>> & {
6
+ onChange?: ((...args: any[]) => any) | undefined;
7
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
8
+ }, {}, {}>;
9
+ export default _default;
10
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
11
+ type __VLS_TypePropsToOption<T> = {
12
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
13
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
14
+ } : {
15
+ type: import('vue').PropType<T[K]>;
16
+ required: true;
17
+ };
18
+ };
@@ -0,0 +1,50 @@
1
+ import { UserSelectorProps } from '../types';
2
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<UserSelectorProps>, {
3
+ apiBaseUrl: string;
4
+ tenantId: string;
5
+ placeholder: string;
6
+ modelValue: string;
7
+ draggable: boolean;
8
+ multiple: boolean;
9
+ currentUserId: string;
10
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ change: (...args: any[]) => void;
12
+ "update:modelValue": (...args: any[]) => void;
13
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<UserSelectorProps>, {
14
+ apiBaseUrl: string;
15
+ tenantId: string;
16
+ placeholder: string;
17
+ modelValue: string;
18
+ draggable: boolean;
19
+ multiple: boolean;
20
+ currentUserId: string;
21
+ }>>> & {
22
+ onChange?: ((...args: any[]) => any) | undefined;
23
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
24
+ }, {
25
+ draggable: boolean;
26
+ modelValue: string | string[];
27
+ placeholder: string;
28
+ apiBaseUrl: string;
29
+ tenantId: string;
30
+ currentUserId: string;
31
+ multiple: boolean;
32
+ }, {}>;
33
+ export default _default;
34
+ type __VLS_WithDefaults<P, D> = {
35
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
36
+ default: D[K];
37
+ }> : P[K];
38
+ };
39
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
40
+ type __VLS_TypePropsToOption<T> = {
41
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
42
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
43
+ } : {
44
+ type: import('vue').PropType<T[K]>;
45
+ required: true;
46
+ };
47
+ };
48
+ type __VLS_PrettifyLocal<T> = {
49
+ [K in keyof T]: T[K];
50
+ } & {};
@@ -0,0 +1,68 @@
1
+ import { FormattedUser } from '../types';
2
+ declare const _default: import("vue").DefineComponent<__VLS_TypePropsToOption<{
3
+ /**
4
+ * 用户信息
5
+ */
6
+ user: FormattedUser;
7
+ /**
8
+ * 租户数据映射
9
+ */
10
+ tenants: Record<string, string>;
11
+ /**
12
+ * 当前租户ID
13
+ */
14
+ currentTenantId?: string;
15
+ /**
16
+ * 是否可拖拽
17
+ */
18
+ draggable?: boolean;
19
+ /**
20
+ * 是否激活状态
21
+ */
22
+ active?: boolean;
23
+ /**
24
+ * 是否显示租户信息
25
+ */
26
+ showTenant?: boolean;
27
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
28
+ click: (...args: any[]) => void;
29
+ close: (...args: any[]) => void;
30
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToOption<{
31
+ /**
32
+ * 用户信息
33
+ */
34
+ user: FormattedUser;
35
+ /**
36
+ * 租户数据映射
37
+ */
38
+ tenants: Record<string, string>;
39
+ /**
40
+ * 当前租户ID
41
+ */
42
+ currentTenantId?: string;
43
+ /**
44
+ * 是否可拖拽
45
+ */
46
+ draggable?: boolean;
47
+ /**
48
+ * 是否激活状态
49
+ */
50
+ active?: boolean;
51
+ /**
52
+ * 是否显示租户信息
53
+ */
54
+ showTenant?: boolean;
55
+ }>>> & {
56
+ onClick?: ((...args: any[]) => any) | undefined;
57
+ onClose?: ((...args: any[]) => any) | undefined;
58
+ }, {}, {}>;
59
+ export default _default;
60
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
61
+ type __VLS_TypePropsToOption<T> = {
62
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
63
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
64
+ } : {
65
+ type: import('vue').PropType<T[K]>;
66
+ required: true;
67
+ };
68
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 租户数据处理 Hook
3
+ * @module hooks/useTenantData
4
+ */
5
+ import { type Ref } from 'vue';
6
+ /**
7
+ * 使用租户数据的Hook
8
+ * @param apiBaseUrl - API基础URL
9
+ * @param tenantId - 租户ID
10
+ * @returns 租户数据和加载状态
11
+ */
12
+ export declare const useTenantData: (apiBaseUrl: string, tenantId: string) => {
13
+ tenants: Ref<Record<string, string>>;
14
+ loading: Ref<boolean>;
15
+ fetchTenants: () => Promise<void>;
16
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 用户搜索 Hook
3
+ * @module hooks/useUserSearch
4
+ */
5
+ import { type Ref } from 'vue';
6
+ import { type FormattedUser } from '../types';
7
+ /**
8
+ * 使用用户搜索的Hook
9
+ * @param apiBaseUrl - API基础URL
10
+ * @param tenantId - 租户ID
11
+ * @returns 用户搜索相关状态和方法
12
+ */
13
+ export declare const useUserSearch: (apiBaseUrl: string, tenantId: string) => {
14
+ searchResults: Ref<FormattedUser[]>;
15
+ loading: Ref<boolean>;
16
+ searchQuery: Ref<string>;
17
+ performSearch: (keyword: string) => Promise<void>;
18
+ handleSearchInput: (value: string) => void;
19
+ clearSearch: () => void;
20
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 用户选择 Hook
3
+ * @module hooks/useUserSelection
4
+ */
5
+ import { type Ref } from 'vue';
6
+ import { type FormattedUser } from '../types';
7
+ /**
8
+ * 使用用户选择的Hook
9
+ * @param apiBaseUrl - API基础URL
10
+ * @param tenantId - 租户ID
11
+ * @param initialSelectedUsers - 初始选中的用户ID
12
+ * @param multiple - 是否多选
13
+ * @returns 用户选择相关状态和方法
14
+ */
15
+ export declare const useUserSelection: (apiBaseUrl: string, tenantId: string, initialSelectedUsers?: string | string[], multiple?: boolean) => {
16
+ selectedUsers: Ref<FormattedUser[]>;
17
+ selectedUserIds: import("vue").ComputedRef<string | string[]>;
18
+ loading: Ref<boolean>;
19
+ addUser: (user: FormattedUser) => void;
20
+ removeUser: (user: FormattedUser) => void;
21
+ removeUserAtIndex: (index: number) => void;
22
+ clearSelection: () => void;
23
+ };
@@ -0,0 +1,121 @@
1
+ /**
2
+ * 用户对象接口
3
+ */
4
+ export interface User {
5
+ /**
6
+ * 用户名
7
+ */
8
+ bk_username: string;
9
+ /**
10
+ * 数据源类型
11
+ */
12
+ data_source_type: string;
13
+ /**
14
+ * 显示名称
15
+ */
16
+ display_name: string;
17
+ /**
18
+ * 全名
19
+ */
20
+ full_name: string;
21
+ /**
22
+ * 登录名
23
+ */
24
+ login_name: string;
25
+ /**
26
+ * 所属租户ID
27
+ */
28
+ owner_tenant_id: string;
29
+ }
30
+ /**
31
+ * 格式化后的用户信息
32
+ */
33
+ export interface FormattedUser {
34
+ /**
35
+ * 用户ID
36
+ */
37
+ id: string;
38
+ /**
39
+ * 用户名称
40
+ */
41
+ name: string;
42
+ /**
43
+ * 租户ID
44
+ */
45
+ tenantId?: string;
46
+ }
47
+ /**
48
+ * 租户信息
49
+ */
50
+ export interface Tenant {
51
+ /**
52
+ * 租户ID
53
+ */
54
+ id: string;
55
+ /**
56
+ * 租户名称
57
+ */
58
+ name: string;
59
+ }
60
+ /**
61
+ * 用户选择器属性
62
+ */
63
+ export interface UserSelectorProps {
64
+ /**
65
+ * 接口基础URL
66
+ */
67
+ apiBaseUrl: string;
68
+ /**
69
+ * 租户ID
70
+ */
71
+ tenantId: string;
72
+ /**
73
+ * 占位文字
74
+ */
75
+ placeholder?: string;
76
+ /**
77
+ * 默认选中的用户(单选时为字符串,多选时为数组)
78
+ */
79
+ modelValue?: string | string[];
80
+ /**
81
+ * 是否支持拖拽排序
82
+ */
83
+ draggable?: boolean;
84
+ /**
85
+ * 是否多选
86
+ */
87
+ multiple?: boolean;
88
+ /**
89
+ * 本人ID
90
+ */
91
+ currentUserId?: string;
92
+ }
93
+ /**
94
+ * 单选模式属性
95
+ */
96
+ export interface SingleSelectorProps {
97
+ /**
98
+ * 选中的用户ID
99
+ */
100
+ modelValue?: string;
101
+ /**
102
+ * 占位文字
103
+ */
104
+ placeholder?: string;
105
+ /**
106
+ * 接口基础URL
107
+ */
108
+ apiBaseUrl?: string;
109
+ /**
110
+ * 租户ID
111
+ */
112
+ tenantId?: string;
113
+ /**
114
+ * 租户信息映射
115
+ */
116
+ tenants: Record<string, string>;
117
+ /**
118
+ * 本人ID
119
+ */
120
+ currentUserId?: string;
121
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 通用工具函数
3
+ * @module utils/common
4
+ */
5
+ import { type FormattedUser } from '../types';
6
+ /**
7
+ * 防抖函数
8
+ * @param fn - 需要防抖的函数
9
+ * @param delay - 延迟时间(毫秒)
10
+ * @returns 防抖后的函数
11
+ */
12
+ export declare const debounce: <T extends (...args: any[]) => any>(fn: T, delay: number) => (...args: Parameters<T>) => void;
13
+ /**
14
+ * 计算标签容器可见数量
15
+ * @param container - 容器元素
16
+ * @param items - 项目元素列表
17
+ * @param containerWidth - 容器宽度
18
+ * @returns 可见项目数量
19
+ */
20
+ export declare const calculateVisibleTags: (container: HTMLElement, items: HTMLElement[] | NodeListOf<Element>, containerWidth: number) => number;
21
+ /**
22
+ * 转换用户数组为Map结构,方便快速查找
23
+ * @param users - 用户列表
24
+ * @returns 用户Map对象
25
+ */
26
+ export declare const userArrayToMap: (users: FormattedUser[]) => Map<string, FormattedUser>;
27
+ /**
28
+ * 判断两个数组是否有值的变化
29
+ * @param arr1 - 数组1
30
+ * @param arr2 - 数组2
31
+ * @returns 是否有变化
32
+ */
33
+ export declare const hasArrayChanged: (arr1?: any[], arr2?: any[]) => boolean;
package/typings/vue2.d.ts CHANGED
@@ -1,2 +1,16 @@
1
- declare const _default: any;
1
+ import BkUserSelector from './components/user-selector.vue';
2
+ declare const _default: {
3
+ beforeDestroy(): void;
4
+ created(): void;
5
+ data(): {
6
+ app: null;
7
+ unWatchStack: never[];
8
+ };
9
+ mounted(): void;
10
+ name: string;
11
+ props: any;
12
+ render(createElement: any): any;
13
+ };
2
14
  export default _default;
15
+ export { BkUserSelector };
16
+ export * from './types';