@blueking/bk-user-selector 0.0.39-beta.3 → 0.1.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.
@@ -1,586 +1,225 @@
1
- import { unref, ref, onBeforeMount, defineComponent, openBlock, createElementBlock, normalizeClass, withModifiers, toDisplayString, createCommentVNode, h, computed, createBlock, withCtx, createVNode, createElementVNode, Fragment, renderList, renderSlot, watch, nextTick, onMounted, withDirectives, isRef, vModelText, createTextVNode } from "vue";
2
- import { Popover, Loading, Tag, clickoutside, provideGlobalConfig } from "bkui-vue";
3
- const generateCallbackName = () => {
4
- const timestamp = Date.now();
5
- const random = Math.random().toString(36).slice(2, 9);
6
- return `__jsonp_callback_${timestamp}_${random}`;
7
- };
8
- const jsonpRequest = (requestUrl, options = {}) => {
9
- return new Promise((resolve, reject) => {
10
- const url = unref(requestUrl);
11
- const { timeout = 1e3 * 60 * 2, params } = options;
12
- const callbackName = generateCallbackName();
13
- const script = document.createElement("script");
14
- let timeoutId = null;
15
- script.setAttribute("type", "text/javascript");
16
- const cleanup = () => {
17
- if (timeoutId) {
18
- clearTimeout(timeoutId);
1
+ import { unref, ref, watch, onUnmounted, onBeforeMount, computed, defineComponent, openBlock, createElementBlock, normalizeClass, withModifiers, toDisplayString, createCommentVNode, h, createBlock, withCtx, createElementVNode, createVNode, Fragment, renderList, renderSlot, toRef, nextTick, onMounted, withDirectives, mergeProps, isRef, normalizeStyle, vModelText, vShow, createTextVNode } from "vue";
2
+ import { Popover, Loading, Tag, provideGlobalConfig } from "bkui-vue";
3
+ var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
4
+ function getDefaultExportFromCjs(x) {
5
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
6
+ }
7
+ var Sortable$1 = { exports: {} };
8
+ /**!
9
+ * Sortable 1.15.6
10
+ * @author RubaXa <trash@rubaxa.org>
11
+ * @author owenm <owen23355@gmail.com>
12
+ * @license MIT
13
+ */
14
+ (function(module, exports) {
15
+ (function(global2, factory) {
16
+ module.exports = factory();
17
+ })(commonjsGlobal, function() {
18
+ function ownKeys(object, enumerableOnly) {
19
+ var keys = Object.keys(object);
20
+ if (Object.getOwnPropertySymbols) {
21
+ var symbols = Object.getOwnPropertySymbols(object);
22
+ if (enumerableOnly) {
23
+ symbols = symbols.filter(function(sym) {
24
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
25
+ });
26
+ }
27
+ keys.push.apply(keys, symbols);
19
28
  }
20
- if (script.parentNode) {
21
- script.parentNode.removeChild(script);
29
+ return keys;
30
+ }
31
+ function _objectSpread2(target) {
32
+ for (var i = 1; i < arguments.length; i++) {
33
+ var source = arguments[i] != null ? arguments[i] : {};
34
+ if (i % 2) {
35
+ ownKeys(Object(source), true).forEach(function(key) {
36
+ _defineProperty(target, key, source[key]);
37
+ });
38
+ } else if (Object.getOwnPropertyDescriptors) {
39
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
40
+ } else {
41
+ ownKeys(Object(source)).forEach(function(key) {
42
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
43
+ });
44
+ }
22
45
  }
23
- if (window[callbackName]) {
24
- delete window[callbackName];
46
+ return target;
47
+ }
48
+ function _typeof(obj) {
49
+ "@babel/helpers - typeof";
50
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
51
+ _typeof = function(obj2) {
52
+ return typeof obj2;
53
+ };
54
+ } else {
55
+ _typeof = function(obj2) {
56
+ return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2;
57
+ };
25
58
  }
26
- };
27
- window[callbackName] = (data) => {
28
- cleanup();
29
- resolve(data.data || data);
30
- };
31
- timeoutId = setTimeout(() => {
32
- cleanup();
33
- reject(new Error(`JSONP request timeout: ${url}`));
34
- }, timeout);
35
- script.onerror = () => {
36
- cleanup();
37
- reject(new Error(`JSONP request failed: ${url}`));
38
- };
39
- const separator = url.includes("?") ? "&" : "?";
40
- const paramsStr = params ? `&${Object.entries(params).map(([key, value]) => value ? `${key}=${value}` : "").filter(Boolean).join("&")}` : "";
41
- script.src = `${url}${separator}callback=${callbackName}${paramsStr}`;
42
- document.head.appendChild(script);
43
- });
44
- };
45
- const getTenants = async (apiBaseUrl, tenantId) => {
46
- if (!apiBaseUrl || !tenantId) {
47
- console.warn("获取租户信息需要提供有效的apiBaseUrl和租户ID");
48
- return [];
49
- }
50
- try {
51
- const url = `${apiBaseUrl}/api/v3/open-web/tenant/data-source-owner-tenants/`;
52
- const response = await fetch(url, {
53
- method: "GET",
54
- headers: {
55
- "x-bk-tenant-id": tenantId
56
- },
57
- credentials: "include"
58
- });
59
- if (!response.ok) {
60
- throw new Error(`获取租户信息失败: ${response.status} ${response.statusText}`);
59
+ return _typeof(obj);
61
60
  }
62
- const data = await response.json();
63
- return data.data || [];
64
- } catch (error) {
65
- console.error("获取租户信息失败:", error);
66
- return [];
67
- }
68
- };
69
- const searchUsers = async (params) => {
70
- const { apiBaseUrl, tenantId, keyword, enableMultiTenantMode = true } = params;
71
- if (!enableMultiTenantMode) {
72
- const userList = await getUserList(apiBaseUrl, {
73
- keyword,
74
- pageSize: 100,
75
- page: 1
76
- }).catch(() => {
77
- return [];
78
- });
79
- return userList;
80
- }
81
- if (!keyword || !apiBaseUrl || !tenantId) {
82
- console.warn("搜索用户需要提供有效的apiBaseUrl、租户ID和关键词");
83
- return [];
84
- }
85
- try {
86
- const url = `${apiBaseUrl}/api/v3/open-web/tenant/users/-/search/?keyword=${encodeURIComponent(keyword)}`;
87
- const response = await fetch(url, {
88
- method: "GET",
89
- headers: {
90
- "x-bk-tenant-id": tenantId
91
- },
92
- credentials: "include"
93
- });
94
- if (!response.ok) {
95
- throw new Error(`搜索用户失败: ${response.status} ${response.statusText}`);
61
+ function _defineProperty(obj, key, value) {
62
+ if (key in obj) {
63
+ Object.defineProperty(obj, key, {
64
+ value,
65
+ enumerable: true,
66
+ configurable: true,
67
+ writable: true
68
+ });
69
+ } else {
70
+ obj[key] = value;
71
+ }
72
+ return obj;
96
73
  }
97
- const data = await response.json();
98
- return data.data || [];
99
- } catch (error) {
100
- console.error("搜索用户失败:", error);
101
- return [];
102
- }
103
- };
104
- const lookupUsers = async (params) => {
105
- const { apiBaseUrl, tenantId, exactSearchKey = "bk_username", usersList = [], enableMultiTenantMode = true } = params;
106
- const users = usersList.filter((user) => user).map((user) => user.trim());
107
- if (!enableMultiTenantMode) {
108
- const userList = await getUserList(apiBaseUrl, {
109
- userIds: users
110
- }).catch(() => {
111
- return [];
112
- });
113
- return users.map((user) => userList.find((u) => u.username === user)).filter(Boolean);
114
- }
115
- if (users.length === 0 || !apiBaseUrl || !tenantId) {
116
- console.warn("批量查找用户需要提供有效的apiBaseUrl、租户ID和至少一个用户名");
117
- return [];
118
- }
119
- try {
120
- const url = `${apiBaseUrl}/api/v3/open-web/tenant/users/-/lookup/?lookups=${users.join(",")}&lookup_fields=${exactSearchKey}`;
121
- const response = await fetch(url, {
122
- method: "GET",
123
- headers: {
124
- "x-bk-tenant-id": tenantId
125
- },
126
- credentials: "include"
127
- });
128
- if (!response.ok) {
129
- throw new Error(`批量查找用户失败: ${response.status} ${response.statusText}`);
74
+ function _extends() {
75
+ _extends = Object.assign || function(target) {
76
+ for (var i = 1; i < arguments.length; i++) {
77
+ var source = arguments[i];
78
+ for (var key in source) {
79
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
80
+ target[key] = source[key];
81
+ }
82
+ }
83
+ }
84
+ return target;
85
+ };
86
+ return _extends.apply(this, arguments);
130
87
  }
131
- const data = await response.json();
132
- return data.data || [];
133
- } catch (error) {
134
- console.error("批量查找用户失败:", error);
135
- return [];
136
- }
137
- };
138
- const formatUsers = (users, enableMultiTenantMode = true) => {
139
- if (!users || !Array.isArray(users)) return [];
140
- if (!enableMultiTenantMode) {
141
- return users.map((user) => ({
142
- ...user,
143
- id: user.username,
144
- name: `${user.display_name}(${user.username})`,
145
- tenantId: user.owner_tenant_id
146
- }));
147
- }
148
- return users.map((user) => ({
149
- id: user.bk_username,
150
- name: user.display_name,
151
- tenantId: user.owner_tenant_id,
152
- ...user
153
- }));
154
- };
155
- const getUserList = async (url, params) => {
156
- const { userIds, keyword, pageSize = 20, page, appCode } = params;
157
- const data = await jsonpRequest(url, {
158
- params: {
159
- exact_lookups: (userIds == null ? void 0 : userIds.join(",")) || void 0,
160
- fuzzy_lookups: keyword || void 0,
161
- page_size: Math.max((userIds == null ? void 0 : userIds.length) || 0, 20, Number(pageSize)).toString(),
162
- page: (page == null ? void 0 : page.toString()) || "1",
163
- app_code: appCode || "bk-magicbox"
88
+ function _objectWithoutPropertiesLoose(source, excluded) {
89
+ if (source == null) return {};
90
+ var target = {};
91
+ var sourceKeys = Object.keys(source);
92
+ var key, i;
93
+ for (i = 0; i < sourceKeys.length; i++) {
94
+ key = sourceKeys[i];
95
+ if (excluded.indexOf(key) >= 0) continue;
96
+ target[key] = source[key];
97
+ }
98
+ return target;
164
99
  }
165
- });
166
- return (data == null ? void 0 : data.results) || [];
167
- };
168
- /*! js-cookie v3.0.5 | MIT */
169
- function assign(target) {
170
- for (var i = 1; i < arguments.length; i++) {
171
- var source = arguments[i];
172
- for (var key in source) {
173
- target[key] = source[key];
100
+ function _objectWithoutProperties(source, excluded) {
101
+ if (source == null) return {};
102
+ var target = _objectWithoutPropertiesLoose(source, excluded);
103
+ var key, i;
104
+ if (Object.getOwnPropertySymbols) {
105
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
106
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
107
+ key = sourceSymbolKeys[i];
108
+ if (excluded.indexOf(key) >= 0) continue;
109
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
110
+ target[key] = source[key];
111
+ }
112
+ }
113
+ return target;
174
114
  }
175
- }
176
- return target;
177
- }
178
- var defaultConverter = {
179
- read: function(value) {
180
- if (value[0] === '"') {
181
- value = value.slice(1, -1);
115
+ function _toConsumableArray(arr) {
116
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
182
117
  }
183
- return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
184
- },
185
- write: function(value) {
186
- return encodeURIComponent(value).replace(
187
- /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
188
- decodeURIComponent
189
- );
190
- }
191
- };
192
- function init(converter, defaultAttributes) {
193
- function set(name, value, attributes) {
194
- if (typeof document === "undefined") {
195
- return;
196
- }
197
- attributes = assign({}, defaultAttributes, attributes);
198
- if (typeof attributes.expires === "number") {
199
- attributes.expires = new Date(Date.now() + attributes.expires * 864e5);
118
+ function _arrayWithoutHoles(arr) {
119
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
200
120
  }
201
- if (attributes.expires) {
202
- attributes.expires = attributes.expires.toUTCString();
121
+ function _iterableToArray(iter) {
122
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
203
123
  }
204
- name = encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
205
- var stringifiedAttributes = "";
206
- for (var attributeName in attributes) {
207
- if (!attributes[attributeName]) {
208
- continue;
209
- }
210
- stringifiedAttributes += "; " + attributeName;
211
- if (attributes[attributeName] === true) {
212
- continue;
213
- }
214
- stringifiedAttributes += "=" + attributes[attributeName].split(";")[0];
124
+ function _unsupportedIterableToArray(o, minLen) {
125
+ if (!o) return;
126
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
127
+ var n = Object.prototype.toString.call(o).slice(8, -1);
128
+ if (n === "Object" && o.constructor) n = o.constructor.name;
129
+ if (n === "Map" || n === "Set") return Array.from(o);
130
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
215
131
  }
216
- return document.cookie = name + "=" + converter.write(value, name) + stringifiedAttributes;
217
- }
218
- function get(name) {
219
- if (typeof document === "undefined" || arguments.length && !name) {
220
- return;
132
+ function _arrayLikeToArray(arr, len) {
133
+ if (len == null || len > arr.length) len = arr.length;
134
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
135
+ return arr2;
221
136
  }
222
- var cookies = document.cookie ? document.cookie.split("; ") : [];
223
- var jar = {};
224
- for (var i = 0; i < cookies.length; i++) {
225
- var parts = cookies[i].split("=");
226
- var value = parts.slice(1).join("=");
227
- try {
228
- var found = decodeURIComponent(parts[0]);
229
- jar[found] = converter.read(value, found);
230
- if (name === found) {
231
- break;
232
- }
233
- } catch (e) {
234
- }
137
+ function _nonIterableSpread() {
138
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
235
139
  }
236
- return name ? jar[name] : jar;
237
- }
238
- return Object.create(
239
- {
240
- set,
241
- get,
242
- remove: function(name, attributes) {
243
- set(
244
- name,
245
- "",
246
- assign({}, attributes, {
247
- expires: -1
248
- })
249
- );
250
- },
251
- withAttributes: function(attributes) {
252
- return init(this.converter, assign({}, this.attributes, attributes));
253
- },
254
- withConverter: function(converter2) {
255
- return init(assign({}, this.converter, converter2), this.attributes);
140
+ var version = "1.15.6";
141
+ function userAgent(pattern) {
142
+ if (typeof window !== "undefined" && window.navigator) {
143
+ return !!/* @__PURE__ */ navigator.userAgent.match(pattern);
256
144
  }
257
- },
258
- {
259
- attributes: { value: Object.freeze(defaultAttributes) },
260
- converter: { value: Object.freeze(converter) }
261
145
  }
262
- );
263
- }
264
- var api = init(defaultConverter, { path: "/" });
265
- const enUS = {
266
- 我: "Me",
267
- 请输入人员名称搜索: "Please enter the name of the user to search",
268
- 用户群组: "User Group",
269
- 无匹配人员: "No matching users",
270
- 虚拟账号: "Virtual Account",
271
- 用户: "User"
272
- };
273
- const zhCN = {
274
- 我: "我",
275
- 请输入人员名称搜索: "请输入人员名称搜索",
276
- 用户群组: "用户群组",
277
- 无匹配人员: "无匹配人员",
278
- 虚拟账号: "虚拟账号",
279
- 用户: "用户"
280
- };
281
- const BLUEKINNG_LANGUAGE = "blueking_language";
282
- const languageMap = {
283
- "en-US": enUS,
284
- "zh-CN": zhCN
285
- };
286
- const getPath = (obj, path, variables) => {
287
- const pathStack = /^\w/.test(path) ? path.split(".") : [path];
288
- const { length } = pathStack;
289
- let target = obj;
290
- let i = 0;
291
- while (i <= length && target) {
292
- if (typeof target === "string") {
293
- return target;
146
+ var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
147
+ var Edge = userAgent(/Edge/i);
148
+ var FireFox = userAgent(/firefox/i);
149
+ var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
150
+ var IOS = userAgent(/iP(ad|od|hone)/i);
151
+ var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
152
+ var captureMode = {
153
+ capture: false,
154
+ passive: false
155
+ };
156
+ function on(el, event, fn) {
157
+ el.addEventListener(event, fn, !IE11OrLess && captureMode);
294
158
  }
295
- if (variables) {
296
- target = target[pathStack[i]];
297
- Object.keys(variables).forEach((key) => {
298
- target = target.replace(`{${key}}`, variables[key]);
299
- });
300
- } else {
301
- target = target[pathStack[i]];
159
+ function off(el, event, fn) {
160
+ el.removeEventListener(event, fn, !IE11OrLess && captureMode);
302
161
  }
303
- i = i + 1;
304
- if (!target) {
305
- return target;
162
+ function matches(el, selector) {
163
+ if (!selector) return;
164
+ selector[0] === ">" && (selector = selector.substring(1));
165
+ if (el) {
166
+ try {
167
+ if (el.matches) {
168
+ return el.matches(selector);
169
+ } else if (el.msMatchesSelector) {
170
+ return el.msMatchesSelector(selector);
171
+ } else if (el.webkitMatchesSelector) {
172
+ return el.webkitMatchesSelector(selector);
173
+ }
174
+ } catch (_) {
175
+ return false;
176
+ }
177
+ }
178
+ return false;
306
179
  }
307
- }
308
- return target;
309
- };
310
- const useI18n = () => {
311
- let localeLanguage = "zh-CN";
312
- const bluekingLanguage = api.get(BLUEKINNG_LANGUAGE);
313
- if (bluekingLanguage && bluekingLanguage.toLowerCase() === "en") {
314
- localeLanguage = "en-US";
315
- }
316
- const languagePackage = languageMap[localeLanguage];
317
- const t = (path, variable) => {
318
- const value = getPath(languagePackage, path, variable);
319
- if (value === void 0) {
320
- console.warn(`缺少索引 * ${path} *`);
180
+ function getParentOrHost(el) {
181
+ return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode;
321
182
  }
322
- return value;
323
- };
324
- return {
325
- local: localeLanguage,
326
- t
327
- };
328
- };
329
- const useTenantData = (apiBaseUrl, tenantId, enableMultiTenantMode = true) => {
330
- const tenants = ref({});
331
- const loading = ref(false);
332
- const fetchTenants = async () => {
333
- if (!apiBaseUrl || !tenantId) {
334
- console.warn("获取租户需要提供有效的API基础URL和租户ID");
335
- return;
183
+ function closest(el, selector, ctx, includeCTX) {
184
+ if (el) {
185
+ ctx = ctx || document;
186
+ do {
187
+ if (selector != null && (selector[0] === ">" ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
188
+ return el;
189
+ }
190
+ if (el === ctx) break;
191
+ } while (el = getParentOrHost(el));
192
+ }
193
+ return null;
336
194
  }
337
- loading.value = true;
338
- try {
339
- const result = await getTenants(apiBaseUrl, tenantId);
340
- const tenantMap = {};
341
- result.forEach((item) => {
342
- if (item.id && item.name) {
343
- tenantMap[item.id] = item.name;
195
+ var R_SPACE = /\s+/g;
196
+ function toggleClass(el, name, state) {
197
+ if (el && name) {
198
+ if (el.classList) {
199
+ el.classList[state ? "add" : "remove"](name);
200
+ } else {
201
+ var className = (" " + el.className + " ").replace(R_SPACE, " ").replace(" " + name + " ", " ");
202
+ el.className = (className + (state ? " " + name : "")).replace(R_SPACE, " ");
344
203
  }
345
- });
346
- tenants.value = tenantMap;
347
- } catch (error) {
348
- console.error("获取租户数据失败:", error);
349
- } finally {
350
- loading.value = false;
204
+ }
351
205
  }
352
- };
353
- onBeforeMount(() => {
354
- if (enableMultiTenantMode) {
355
- fetchTenants();
356
- }
357
- });
358
- return {
359
- tenants,
360
- loading,
361
- fetchTenants
362
- };
363
- };
364
- var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
365
- function getDefaultExportFromCjs(x) {
366
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
367
- }
368
- var Sortable$1 = { exports: {} };
369
- /**!
370
- * Sortable 1.15.6
371
- * @author RubaXa <trash@rubaxa.org>
372
- * @author owenm <owen23355@gmail.com>
373
- * @license MIT
374
- */
375
- (function(module, exports) {
376
- (function(global2, factory) {
377
- module.exports = factory();
378
- })(commonjsGlobal, function() {
379
- function ownKeys(object, enumerableOnly) {
380
- var keys = Object.keys(object);
381
- if (Object.getOwnPropertySymbols) {
382
- var symbols = Object.getOwnPropertySymbols(object);
383
- if (enumerableOnly) {
384
- symbols = symbols.filter(function(sym) {
385
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
386
- });
387
- }
388
- keys.push.apply(keys, symbols);
389
- }
390
- return keys;
391
- }
392
- function _objectSpread2(target) {
393
- for (var i = 1; i < arguments.length; i++) {
394
- var source = arguments[i] != null ? arguments[i] : {};
395
- if (i % 2) {
396
- ownKeys(Object(source), true).forEach(function(key) {
397
- _defineProperty(target, key, source[key]);
398
- });
399
- } else if (Object.getOwnPropertyDescriptors) {
400
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
401
- } else {
402
- ownKeys(Object(source)).forEach(function(key) {
403
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
404
- });
405
- }
406
- }
407
- return target;
408
- }
409
- function _typeof(obj) {
410
- "@babel/helpers - typeof";
411
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
412
- _typeof = function(obj2) {
413
- return typeof obj2;
414
- };
415
- } else {
416
- _typeof = function(obj2) {
417
- return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2;
418
- };
419
- }
420
- return _typeof(obj);
421
- }
422
- function _defineProperty(obj, key, value) {
423
- if (key in obj) {
424
- Object.defineProperty(obj, key, {
425
- value,
426
- enumerable: true,
427
- configurable: true,
428
- writable: true
429
- });
430
- } else {
431
- obj[key] = value;
432
- }
433
- return obj;
434
- }
435
- function _extends() {
436
- _extends = Object.assign || function(target) {
437
- for (var i = 1; i < arguments.length; i++) {
438
- var source = arguments[i];
439
- for (var key in source) {
440
- if (Object.prototype.hasOwnProperty.call(source, key)) {
441
- target[key] = source[key];
442
- }
443
- }
444
- }
445
- return target;
446
- };
447
- return _extends.apply(this, arguments);
448
- }
449
- function _objectWithoutPropertiesLoose(source, excluded) {
450
- if (source == null) return {};
451
- var target = {};
452
- var sourceKeys = Object.keys(source);
453
- var key, i;
454
- for (i = 0; i < sourceKeys.length; i++) {
455
- key = sourceKeys[i];
456
- if (excluded.indexOf(key) >= 0) continue;
457
- target[key] = source[key];
458
- }
459
- return target;
460
- }
461
- function _objectWithoutProperties(source, excluded) {
462
- if (source == null) return {};
463
- var target = _objectWithoutPropertiesLoose(source, excluded);
464
- var key, i;
465
- if (Object.getOwnPropertySymbols) {
466
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
467
- for (i = 0; i < sourceSymbolKeys.length; i++) {
468
- key = sourceSymbolKeys[i];
469
- if (excluded.indexOf(key) >= 0) continue;
470
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
471
- target[key] = source[key];
472
- }
473
- }
474
- return target;
475
- }
476
- function _toConsumableArray(arr) {
477
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
478
- }
479
- function _arrayWithoutHoles(arr) {
480
- if (Array.isArray(arr)) return _arrayLikeToArray(arr);
481
- }
482
- function _iterableToArray(iter) {
483
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
484
- }
485
- function _unsupportedIterableToArray(o, minLen) {
486
- if (!o) return;
487
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
488
- var n = Object.prototype.toString.call(o).slice(8, -1);
489
- if (n === "Object" && o.constructor) n = o.constructor.name;
490
- if (n === "Map" || n === "Set") return Array.from(o);
491
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
492
- }
493
- function _arrayLikeToArray(arr, len) {
494
- if (len == null || len > arr.length) len = arr.length;
495
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
496
- return arr2;
497
- }
498
- function _nonIterableSpread() {
499
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
500
- }
501
- var version = "1.15.6";
502
- function userAgent(pattern) {
503
- if (typeof window !== "undefined" && window.navigator) {
504
- return !!/* @__PURE__ */ navigator.userAgent.match(pattern);
505
- }
506
- }
507
- var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
508
- var Edge = userAgent(/Edge/i);
509
- var FireFox = userAgent(/firefox/i);
510
- var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
511
- var IOS = userAgent(/iP(ad|od|hone)/i);
512
- var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
513
- var captureMode = {
514
- capture: false,
515
- passive: false
516
- };
517
- function on(el, event, fn) {
518
- el.addEventListener(event, fn, !IE11OrLess && captureMode);
519
- }
520
- function off(el, event, fn) {
521
- el.removeEventListener(event, fn, !IE11OrLess && captureMode);
522
- }
523
- function matches(el, selector) {
524
- if (!selector) return;
525
- selector[0] === ">" && (selector = selector.substring(1));
526
- if (el) {
527
- try {
528
- if (el.matches) {
529
- return el.matches(selector);
530
- } else if (el.msMatchesSelector) {
531
- return el.msMatchesSelector(selector);
532
- } else if (el.webkitMatchesSelector) {
533
- return el.webkitMatchesSelector(selector);
534
- }
535
- } catch (_) {
536
- return false;
537
- }
538
- }
539
- return false;
540
- }
541
- function getParentOrHost(el) {
542
- return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode;
543
- }
544
- function closest(el, selector, ctx, includeCTX) {
545
- if (el) {
546
- ctx = ctx || document;
547
- do {
548
- if (selector != null && (selector[0] === ">" ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
549
- return el;
550
- }
551
- if (el === ctx) break;
552
- } while (el = getParentOrHost(el));
553
- }
554
- return null;
555
- }
556
- var R_SPACE = /\s+/g;
557
- function toggleClass(el, name, state) {
558
- if (el && name) {
559
- if (el.classList) {
560
- el.classList[state ? "add" : "remove"](name);
561
- } else {
562
- var className = (" " + el.className + " ").replace(R_SPACE, " ").replace(" " + name + " ", " ");
563
- el.className = (className + (state ? " " + name : "")).replace(R_SPACE, " ");
564
- }
565
- }
566
- }
567
- function css(el, prop, val) {
568
- var style = el && el.style;
569
- if (style) {
570
- if (val === void 0) {
571
- if (document.defaultView && document.defaultView.getComputedStyle) {
572
- val = document.defaultView.getComputedStyle(el, "");
573
- } else if (el.currentStyle) {
574
- val = el.currentStyle;
575
- }
576
- return prop === void 0 ? val : val[prop];
577
- } else {
578
- if (!(prop in style) && prop.indexOf("webkit") === -1) {
579
- prop = "-webkit-" + prop;
580
- }
581
- style[prop] = val + (typeof val === "string" ? "" : "px");
582
- }
583
- }
206
+ function css(el, prop, val) {
207
+ var style = el && el.style;
208
+ if (style) {
209
+ if (val === void 0) {
210
+ if (document.defaultView && document.defaultView.getComputedStyle) {
211
+ val = document.defaultView.getComputedStyle(el, "");
212
+ } else if (el.currentStyle) {
213
+ val = el.currentStyle;
214
+ }
215
+ return prop === void 0 ? val : val[prop];
216
+ } else {
217
+ if (!(prop in style) && prop.indexOf("webkit") === -1) {
218
+ prop = "-webkit-" + prop;
219
+ }
220
+ style[prop] = val + (typeof val === "string" ? "" : "px");
221
+ }
222
+ }
584
223
  }
585
224
  function matrix(el, selfOnly) {
586
225
  var appliedTransforms = "";
@@ -3119,15 +2758,580 @@ var Sortable$1 = { exports: {} };
3119
2758
  multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
3120
2759
  });
3121
2760
  }
3122
- Sortable2.mount(new AutoScrollPlugin());
3123
- Sortable2.mount(Remove, Revert);
3124
- Sortable2.mount(new SwapPlugin());
3125
- Sortable2.mount(new MultiDragPlugin());
3126
- return Sortable2;
2761
+ Sortable2.mount(new AutoScrollPlugin());
2762
+ Sortable2.mount(Remove, Revert);
2763
+ Sortable2.mount(new SwapPlugin());
2764
+ Sortable2.mount(new MultiDragPlugin());
2765
+ return Sortable2;
2766
+ });
2767
+ })(Sortable$1);
2768
+ var SortableExports = Sortable$1.exports;
2769
+ const Sortable = /* @__PURE__ */ getDefaultExportFromCjs(SortableExports);
2770
+ const RESERVED_SPACE_FOR_INPUT = 100;
2771
+ const SEARCH_DEBOUNCE_DELAY = 300;
2772
+ const DEFAULT_EXACT_SEARCH_KEY = "bk_username";
2773
+ const USER_TYPE = {
2774
+ /** 普通用户 */
2775
+ USER: "user",
2776
+ /** 虚拟账号 */
2777
+ VIRTUAL: "virtual",
2778
+ /** 自定义用户 */
2779
+ CUSTOM: "custom",
2780
+ /** 用户群组 */
2781
+ USER_GROUP: "userGroup"
2782
+ };
2783
+ const DEFAULT_PAGE_SIZE = 100;
2784
+ const generateCallbackName = () => {
2785
+ const timestamp = Date.now();
2786
+ const random = Math.random().toString(36).slice(2, 9);
2787
+ return `__jsonp_callback_${timestamp}_${random}`;
2788
+ };
2789
+ const jsonpRequest = (requestUrl, options = {}) => {
2790
+ return new Promise((resolve, reject) => {
2791
+ const url = unref(requestUrl);
2792
+ const { timeout = 1e3 * 60 * 2, params } = options;
2793
+ const callbackName = generateCallbackName();
2794
+ const script = document.createElement("script");
2795
+ let timeoutId = null;
2796
+ script.setAttribute("type", "text/javascript");
2797
+ const cleanup = () => {
2798
+ if (timeoutId) {
2799
+ clearTimeout(timeoutId);
2800
+ }
2801
+ if (script.parentNode) {
2802
+ script.parentNode.removeChild(script);
2803
+ }
2804
+ if (window[callbackName]) {
2805
+ delete window[callbackName];
2806
+ }
2807
+ };
2808
+ window[callbackName] = (data) => {
2809
+ cleanup();
2810
+ resolve(data.data || data);
2811
+ };
2812
+ timeoutId = setTimeout(() => {
2813
+ cleanup();
2814
+ reject(new Error(`JSONP request timeout: ${url}`));
2815
+ }, timeout);
2816
+ script.onerror = () => {
2817
+ cleanup();
2818
+ reject(new Error(`JSONP request failed: ${url}`));
2819
+ };
2820
+ const separator = url.includes("?") ? "&" : "?";
2821
+ const paramsStr = params ? `&${Object.entries(params).map(([key, value]) => value ? `${key}=${value}` : "").filter(Boolean).join("&")}` : "";
2822
+ script.src = `${url}${separator}callback=${callbackName}${paramsStr}`;
2823
+ document.head.appendChild(script);
2824
+ });
2825
+ };
2826
+ const logger = {
2827
+ /**
2828
+ * 调试日志
2829
+ */
2830
+ debug: (message, ...args) => {
2831
+ },
2832
+ /**
2833
+ * 信息日志
2834
+ */
2835
+ info: (message, ...args) => {
2836
+ },
2837
+ /**
2838
+ * 警告日志
2839
+ */
2840
+ warn: (message, ...args) => {
2841
+ },
2842
+ /**
2843
+ * 错误日志
2844
+ */
2845
+ error: (message, error) => {
2846
+ }
2847
+ };
2848
+ const warnMissingParams = (operation, params) => {
2849
+ logger.warn(`${operation}需要提供有效的参数: ${params.join(", ")}`);
2850
+ };
2851
+ const getTenants = async (apiBaseUrl, tenantId) => {
2852
+ if (!apiBaseUrl || !tenantId) {
2853
+ warnMissingParams("获取租户信息", ["apiBaseUrl", "tenantId"]);
2854
+ return [];
2855
+ }
2856
+ try {
2857
+ const url = `${apiBaseUrl}/api/v3/open-web/tenant/data-source-owner-tenants/`;
2858
+ const response = await fetch(url, {
2859
+ method: "GET",
2860
+ headers: {
2861
+ "x-bk-tenant-id": tenantId
2862
+ },
2863
+ credentials: "include"
2864
+ });
2865
+ if (!response.ok) {
2866
+ throw new Error(`${response.status} ${response.statusText}`);
2867
+ }
2868
+ const data = await response.json();
2869
+ return data.data || [];
2870
+ } catch (error) {
2871
+ return [];
2872
+ }
2873
+ };
2874
+ const searchUsers = async (params) => {
2875
+ const { apiBaseUrl, tenantId, keyword, enableMultiTenantMode = true } = params;
2876
+ if (!enableMultiTenantMode) {
2877
+ try {
2878
+ return await getUserList(apiBaseUrl, {
2879
+ keyword,
2880
+ pageSize: DEFAULT_PAGE_SIZE,
2881
+ page: 1
2882
+ });
2883
+ } catch {
2884
+ return [];
2885
+ }
2886
+ }
2887
+ if (!keyword || !apiBaseUrl || !tenantId) {
2888
+ warnMissingParams("搜索用户", ["apiBaseUrl", "tenantId", "keyword"]);
2889
+ return [];
2890
+ }
2891
+ try {
2892
+ const url = `${apiBaseUrl}/api/v3/open-web/tenant/users/-/search/?keyword=${encodeURIComponent(keyword)}`;
2893
+ const response = await fetch(url, {
2894
+ method: "GET",
2895
+ headers: {
2896
+ "x-bk-tenant-id": tenantId
2897
+ },
2898
+ credentials: "include"
2899
+ });
2900
+ if (!response.ok) {
2901
+ throw new Error(`${response.status} ${response.statusText}`);
2902
+ }
2903
+ const data = await response.json();
2904
+ return data.data || [];
2905
+ } catch (error) {
2906
+ return [];
2907
+ }
2908
+ };
2909
+ const lookupUsers = async (params) => {
2910
+ const { apiBaseUrl, tenantId, exactSearchKey = "bk_username", usersList = [], enableMultiTenantMode = true } = params;
2911
+ const users = usersList.filter(Boolean).map((user) => user.trim());
2912
+ if (!enableMultiTenantMode) {
2913
+ try {
2914
+ const userList = await getUserList(apiBaseUrl, { userIds: users });
2915
+ return users.map((user) => userList.find((u) => u.username === user)).filter(Boolean);
2916
+ } catch {
2917
+ return [];
2918
+ }
2919
+ }
2920
+ if (users.length === 0 || !apiBaseUrl || !tenantId) {
2921
+ warnMissingParams("批量查找用户", ["apiBaseUrl", "tenantId", "usersList"]);
2922
+ return [];
2923
+ }
2924
+ try {
2925
+ const url = `${apiBaseUrl}/api/v3/open-web/tenant/users/-/lookup/?lookups=${users.join(",")}&lookup_fields=${exactSearchKey}`;
2926
+ const response = await fetch(url, {
2927
+ method: "GET",
2928
+ headers: {
2929
+ "x-bk-tenant-id": tenantId
2930
+ },
2931
+ credentials: "include"
2932
+ });
2933
+ if (!response.ok) {
2934
+ throw new Error(`${response.status} ${response.statusText}`);
2935
+ }
2936
+ const data = await response.json();
2937
+ return data.data || [];
2938
+ } catch (error) {
2939
+ return [];
2940
+ }
2941
+ };
2942
+ const formatUsers = (users, enableMultiTenantMode = true) => {
2943
+ if (!users || !Array.isArray(users)) return [];
2944
+ if (!enableMultiTenantMode) {
2945
+ return users.map((user) => ({
2946
+ ...user,
2947
+ id: user.username,
2948
+ name: `${user.display_name}(${user.username})`,
2949
+ type: user.data_source_type,
2950
+ tenantId: user.owner_tenant_id
2951
+ }));
2952
+ }
2953
+ return users.map((user) => ({
2954
+ id: user.bk_username,
2955
+ name: user.display_name,
2956
+ type: user.data_source_type,
2957
+ tenantId: user.owner_tenant_id,
2958
+ ...user
2959
+ }));
2960
+ };
2961
+ const getUserList = async (url, params) => {
2962
+ const { userIds, keyword, pageSize = 20, page = 1, appCode = "bk-magicbox" } = params;
2963
+ const data = await jsonpRequest(url, {
2964
+ params: {
2965
+ exact_lookups: (userIds == null ? void 0 : userIds.join(",")) || void 0,
2966
+ fuzzy_lookups: keyword || void 0,
2967
+ page_size: Math.max((userIds == null ? void 0 : userIds.length) || 0, 20, Number(pageSize)).toString(),
2968
+ page: page.toString(),
2969
+ app_code: appCode
2970
+ }
2971
+ });
2972
+ return (data == null ? void 0 : data.results) || [];
2973
+ };
2974
+ const useCurrentUser = (options) => {
2975
+ const {
2976
+ apiBaseUrl,
2977
+ tenantId,
2978
+ currentUserId,
2979
+ exactSearchKey = DEFAULT_EXACT_SEARCH_KEY,
2980
+ enableMultiTenantMode = true
2981
+ } = options;
2982
+ const loading = ref(false);
2983
+ const fetchCurrentUser = async () => {
2984
+ if (!currentUserId) {
2985
+ return null;
2986
+ }
2987
+ loading.value = true;
2988
+ try {
2989
+ const result = await lookupUsers({
2990
+ apiBaseUrl,
2991
+ tenantId,
2992
+ exactSearchKey,
2993
+ usersList: [currentUserId],
2994
+ enableMultiTenantMode
2995
+ });
2996
+ const formattedUsers = formatUsers(result, enableMultiTenantMode);
2997
+ return formattedUsers.length > 0 ? formattedUsers[0] : null;
2998
+ } catch (error) {
2999
+ console.error("获取当前用户信息失败:", error);
3000
+ return null;
3001
+ } finally {
3002
+ loading.value = false;
3003
+ }
3004
+ };
3005
+ return {
3006
+ loading,
3007
+ fetchCurrentUser
3008
+ };
3009
+ };
3010
+ /*! js-cookie v3.0.5 | MIT */
3011
+ function assign(target) {
3012
+ for (var i = 1; i < arguments.length; i++) {
3013
+ var source = arguments[i];
3014
+ for (var key in source) {
3015
+ target[key] = source[key];
3016
+ }
3017
+ }
3018
+ return target;
3019
+ }
3020
+ var defaultConverter = {
3021
+ read: function(value) {
3022
+ if (value[0] === '"') {
3023
+ value = value.slice(1, -1);
3024
+ }
3025
+ return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
3026
+ },
3027
+ write: function(value) {
3028
+ return encodeURIComponent(value).replace(
3029
+ /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
3030
+ decodeURIComponent
3031
+ );
3032
+ }
3033
+ };
3034
+ function init(converter, defaultAttributes) {
3035
+ function set(name, value, attributes) {
3036
+ if (typeof document === "undefined") {
3037
+ return;
3038
+ }
3039
+ attributes = assign({}, defaultAttributes, attributes);
3040
+ if (typeof attributes.expires === "number") {
3041
+ attributes.expires = new Date(Date.now() + attributes.expires * 864e5);
3042
+ }
3043
+ if (attributes.expires) {
3044
+ attributes.expires = attributes.expires.toUTCString();
3045
+ }
3046
+ name = encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
3047
+ var stringifiedAttributes = "";
3048
+ for (var attributeName in attributes) {
3049
+ if (!attributes[attributeName]) {
3050
+ continue;
3051
+ }
3052
+ stringifiedAttributes += "; " + attributeName;
3053
+ if (attributes[attributeName] === true) {
3054
+ continue;
3055
+ }
3056
+ stringifiedAttributes += "=" + attributes[attributeName].split(";")[0];
3057
+ }
3058
+ return document.cookie = name + "=" + converter.write(value, name) + stringifiedAttributes;
3059
+ }
3060
+ function get(name) {
3061
+ if (typeof document === "undefined" || arguments.length && !name) {
3062
+ return;
3063
+ }
3064
+ var cookies = document.cookie ? document.cookie.split("; ") : [];
3065
+ var jar = {};
3066
+ for (var i = 0; i < cookies.length; i++) {
3067
+ var parts = cookies[i].split("=");
3068
+ var value = parts.slice(1).join("=");
3069
+ try {
3070
+ var found = decodeURIComponent(parts[0]);
3071
+ jar[found] = converter.read(value, found);
3072
+ if (name === found) {
3073
+ break;
3074
+ }
3075
+ } catch (e) {
3076
+ }
3077
+ }
3078
+ return name ? jar[name] : jar;
3079
+ }
3080
+ return Object.create(
3081
+ {
3082
+ set,
3083
+ get,
3084
+ remove: function(name, attributes) {
3085
+ set(
3086
+ name,
3087
+ "",
3088
+ assign({}, attributes, {
3089
+ expires: -1
3090
+ })
3091
+ );
3092
+ },
3093
+ withAttributes: function(attributes) {
3094
+ return init(this.converter, assign({}, this.attributes, attributes));
3095
+ },
3096
+ withConverter: function(converter2) {
3097
+ return init(assign({}, this.converter, converter2), this.attributes);
3098
+ }
3099
+ },
3100
+ {
3101
+ attributes: { value: Object.freeze(defaultAttributes) },
3102
+ converter: { value: Object.freeze(converter) }
3103
+ }
3104
+ );
3105
+ }
3106
+ var api = init(defaultConverter, { path: "/" });
3107
+ const enUS = {
3108
+ 我: "Me",
3109
+ 请输入人员名称搜索: "Please enter the name of the user to search",
3110
+ 用户群组: "User Group",
3111
+ 无匹配人员: "No matching users",
3112
+ 虚拟账号: "Virtual Account",
3113
+ 用户: "User"
3114
+ };
3115
+ const zhCN = {
3116
+ 我: "我",
3117
+ 请输入人员名称搜索: "请输入人员名称搜索",
3118
+ 用户群组: "用户群组",
3119
+ 无匹配人员: "无匹配人员",
3120
+ 虚拟账号: "虚拟账号",
3121
+ 用户: "用户"
3122
+ };
3123
+ const BLUEKINNG_LANGUAGE = "blueking_language";
3124
+ const languageMap = {
3125
+ "en-US": enUS,
3126
+ "zh-CN": zhCN
3127
+ };
3128
+ const getPath = (obj, path, variables) => {
3129
+ const pathStack = /^\w/.test(path) ? path.split(".") : [path];
3130
+ const { length } = pathStack;
3131
+ let target = obj;
3132
+ let i = 0;
3133
+ while (i <= length && target) {
3134
+ if (typeof target === "string") {
3135
+ return target;
3136
+ }
3137
+ if (variables) {
3138
+ target = target[pathStack[i]];
3139
+ Object.keys(variables).forEach((key) => {
3140
+ target = target.replace(`{${key}}`, variables[key]);
3141
+ });
3142
+ } else {
3143
+ target = target[pathStack[i]];
3144
+ }
3145
+ i = i + 1;
3146
+ if (!target) {
3147
+ return target;
3148
+ }
3149
+ }
3150
+ return target;
3151
+ };
3152
+ const useI18n = () => {
3153
+ let localeLanguage = "zh-CN";
3154
+ const bluekingLanguage = api.get(BLUEKINNG_LANGUAGE);
3155
+ if (bluekingLanguage && bluekingLanguage.toLowerCase() === "en") {
3156
+ localeLanguage = "en-US";
3157
+ }
3158
+ const languagePackage = languageMap[localeLanguage];
3159
+ const t = (path, variable) => {
3160
+ const value = getPath(languagePackage, path, variable);
3161
+ if (value === void 0) {
3162
+ console.warn(`缺少索引 * ${path} *`);
3163
+ }
3164
+ return value;
3165
+ };
3166
+ return {
3167
+ local: localeLanguage,
3168
+ t
3169
+ };
3170
+ };
3171
+ const useInputHandler = (options) => {
3172
+ const {
3173
+ apiBaseUrl,
3174
+ tenantId,
3175
+ searchQuery,
3176
+ selectedUsers,
3177
+ allowCreate = false,
3178
+ freePaste = false,
3179
+ enableMultiTenantMode = true,
3180
+ maxCount = 0,
3181
+ onAddUser,
3182
+ onBatchAddUsers
3183
+ } = options;
3184
+ const isPasting = ref(false);
3185
+ const createCustomUser = (loginName) => ({
3186
+ id: loginName,
3187
+ name: loginName,
3188
+ type: USER_TYPE.CUSTOM,
3189
+ tenantId: "",
3190
+ login_name: loginName
3191
+ });
3192
+ const parsePastedText = (text) => {
3193
+ const usersList = text.split(/[,,;\n\s]+/).filter(Boolean);
3194
+ return usersList.map((user) => user.trim().replace(/\s*\(.*?\)\s*/, "")).filter(Boolean);
3195
+ };
3196
+ const mergeUsers = (existingUsers, newUsers) => {
3197
+ const userMap = /* @__PURE__ */ new Map();
3198
+ for (const user of [...existingUsers, ...newUsers]) {
3199
+ if (!userMap.has(user.id)) {
3200
+ userMap.set(user.id, user);
3201
+ }
3202
+ }
3203
+ return Array.from(userMap.values());
3204
+ };
3205
+ const handleEnterCreate = (event) => {
3206
+ if (event.key !== "Enter" || !allowCreate || !searchQuery.value.trim()) {
3207
+ return;
3208
+ }
3209
+ const customUser = createCustomUser(searchQuery.value.trim());
3210
+ const isDuplicate = selectedUsers.value.some((user) => user.id === customUser.id);
3211
+ if (!isDuplicate) {
3212
+ onAddUser(customUser);
3213
+ }
3214
+ };
3215
+ const handlePaste = async (event) => {
3216
+ var _a, _b;
3217
+ event.preventDefault();
3218
+ const pastedText = (_b = (_a = event.clipboardData) == null ? void 0 : _a.getData("text")) == null ? void 0 : _b.trim();
3219
+ if (!pastedText) return;
3220
+ isPasting.value = true;
3221
+ try {
3222
+ const usersList = parsePastedText(pastedText);
3223
+ if (usersList.length === 0) return;
3224
+ const result = await lookupUsers({
3225
+ apiBaseUrl,
3226
+ tenantId,
3227
+ exactSearchKey: "login_name",
3228
+ usersList,
3229
+ enableMultiTenantMode
3230
+ });
3231
+ const formattedUsers = formatUsers(result, enableMultiTenantMode);
3232
+ if (onBatchAddUsers) {
3233
+ let mergedUsers = mergeUsers(selectedUsers.value, formattedUsers);
3234
+ if (freePaste) {
3235
+ for (const loginName of usersList) {
3236
+ const isDuplicate = mergedUsers.some((item) => item.login_name === loginName || item.id === loginName);
3237
+ if (!isDuplicate) {
3238
+ mergedUsers.push(createCustomUser(loginName));
3239
+ }
3240
+ }
3241
+ }
3242
+ if (maxCount > 0 && mergedUsers.length > maxCount) {
3243
+ mergedUsers = mergedUsers.slice(0, maxCount);
3244
+ }
3245
+ onBatchAddUsers(mergedUsers);
3246
+ } else {
3247
+ if (formattedUsers.length > 0) {
3248
+ onAddUser(formattedUsers[0]);
3249
+ } else if (freePaste && usersList.length > 0) {
3250
+ onAddUser(createCustomUser(usersList[0]));
3251
+ }
3252
+ }
3253
+ } catch (error) {
3254
+ console.error("精准查找用户失败:", error);
3255
+ } finally {
3256
+ isPasting.value = false;
3257
+ }
3258
+ };
3259
+ return {
3260
+ isPasting,
3261
+ parsePastedText,
3262
+ handleEnterCreate,
3263
+ handlePaste
3264
+ };
3265
+ };
3266
+ const useResizeObserver = (target, callback, options = {}) => {
3267
+ const { immediate = true } = options;
3268
+ let observer = null;
3269
+ const cleanup = () => {
3270
+ if (observer) {
3271
+ observer.disconnect();
3272
+ observer = null;
3273
+ }
3274
+ };
3275
+ const observe = () => {
3276
+ cleanup();
3277
+ if (!target.value) return;
3278
+ observer = new ResizeObserver((entries) => {
3279
+ for (const entry of entries) {
3280
+ callback(entry);
3281
+ }
3282
+ });
3283
+ observer.observe(target.value);
3284
+ if (immediate && target.value) {
3285
+ const rect = target.value.getBoundingClientRect();
3286
+ const entry = {
3287
+ target: target.value,
3288
+ contentRect: rect,
3289
+ borderBoxSize: [{ blockSize: rect.height, inlineSize: rect.width }],
3290
+ contentBoxSize: [{ blockSize: rect.height, inlineSize: rect.width }],
3291
+ devicePixelContentBoxSize: [{ blockSize: rect.height, inlineSize: rect.width }]
3292
+ };
3293
+ callback(entry);
3294
+ }
3295
+ };
3296
+ watch(target, observe, { immediate: true });
3297
+ onUnmounted(cleanup);
3298
+ return cleanup;
3299
+ };
3300
+ const useTenantData = (apiBaseUrl, tenantId, enableMultiTenantMode = true) => {
3301
+ const tenants = ref({});
3302
+ const loading = ref(false);
3303
+ const fetchTenants = async () => {
3304
+ if (!apiBaseUrl || !tenantId) {
3305
+ console.warn("获取租户需要提供有效的API基础URL和租户ID");
3306
+ return;
3307
+ }
3308
+ loading.value = true;
3309
+ try {
3310
+ const result = await getTenants(apiBaseUrl, tenantId);
3311
+ const tenantMap = {};
3312
+ result.forEach((item) => {
3313
+ if (item.id && item.name) {
3314
+ tenantMap[item.id] = item.name;
3315
+ }
3316
+ });
3317
+ tenants.value = tenantMap;
3318
+ } catch (error) {
3319
+ console.error("获取租户数据失败:", error);
3320
+ } finally {
3321
+ loading.value = false;
3322
+ }
3323
+ };
3324
+ onBeforeMount(() => {
3325
+ if (enableMultiTenantMode) {
3326
+ fetchTenants();
3327
+ }
3127
3328
  });
3128
- })(Sortable$1);
3129
- var SortableExports = Sortable$1.exports;
3130
- const Sortable = /* @__PURE__ */ getDefaultExportFromCjs(SortableExports);
3329
+ return {
3330
+ tenants,
3331
+ loading,
3332
+ fetchTenants
3333
+ };
3334
+ };
3131
3335
  const debounce = (fn, delay) => {
3132
3336
  let timer = null;
3133
3337
  return function(...args) {
@@ -3166,10 +3370,12 @@ const useUserSearch = (apiBaseUrl, tenantId, enableMultiTenantMode = true) => {
3166
3370
  const performSearch = async (keyword) => {
3167
3371
  if (!(keyword == null ? void 0 : keyword.length)) {
3168
3372
  searchResults.value = [];
3373
+ loading.value = false;
3169
3374
  return;
3170
3375
  }
3171
3376
  if (enableMultiTenantMode && (!apiBaseUrl || !tenantId)) {
3172
3377
  console.warn("执行用户搜索需要提供有效的API基础URL和租户ID");
3378
+ loading.value = false;
3173
3379
  return;
3174
3380
  }
3175
3381
  loading.value = true;
@@ -3188,14 +3394,16 @@ const useUserSearch = (apiBaseUrl, tenantId, enableMultiTenantMode = true) => {
3188
3394
  loading.value = false;
3189
3395
  }
3190
3396
  };
3191
- const debouncedSearch = debounce(performSearch, 300);
3397
+ const debouncedSearch = debounce(performSearch, SEARCH_DEBOUNCE_DELAY);
3192
3398
  const handleSearchInput = (value) => {
3193
- searchQuery.value = value;
3194
- debouncedSearch(value);
3399
+ loading.value = true;
3400
+ searchQuery.value = value.trim();
3401
+ debouncedSearch(searchQuery.value);
3195
3402
  };
3196
3403
  const clearSearch = () => {
3197
3404
  searchQuery.value = "";
3198
3405
  searchResults.value = [];
3406
+ loading.value = false;
3199
3407
  };
3200
3408
  return {
3201
3409
  searchResults,
@@ -3206,26 +3414,57 @@ const useUserSearch = (apiBaseUrl, tenantId, enableMultiTenantMode = true) => {
3206
3414
  clearSearch
3207
3415
  };
3208
3416
  };
3209
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3417
+ const useUserSelection = (options) => {
3418
+ const { selectedUserIds, excludeUserIds, userGroup, searchQuery } = options;
3419
+ const createCustomUser = (loginName) => ({
3420
+ id: loginName,
3421
+ name: loginName,
3422
+ type: USER_TYPE.CUSTOM,
3423
+ tenantId: "",
3424
+ login_name: loginName
3425
+ });
3426
+ const isUserSelected = (userId) => {
3427
+ return selectedUserIds.value.includes(userId);
3428
+ };
3429
+ const filterOptions = (options2) => {
3430
+ return options2.filter((user) => !isUserSelected(user.id)).filter((user) => {
3431
+ var _a;
3432
+ return !((_a = excludeUserIds == null ? void 0 : excludeUserIds.value) == null ? void 0 : _a.includes(user.id));
3433
+ });
3434
+ };
3435
+ const filteredUserGroup = computed(() => {
3436
+ var _a;
3437
+ if (!((_a = userGroup == null ? void 0 : userGroup.value) == null ? void 0 : _a.length)) {
3438
+ return [];
3439
+ }
3440
+ return userGroup.value.filter((group) => {
3441
+ var _a2, _b;
3442
+ const isNotSelectedAndVisible = !isUserSelected(group.id) && !group.hidden;
3443
+ if (!isNotSelectedAndVisible) {
3444
+ return false;
3445
+ }
3446
+ const query = searchQuery.value.trim();
3447
+ if (!query) {
3448
+ return true;
3449
+ }
3450
+ return ((_a2 = group.id) == null ? void 0 : _a2.includes(query)) || ((_b = group.name) == null ? void 0 : _b.includes(query));
3451
+ });
3452
+ });
3453
+ return {
3454
+ createCustomUser,
3455
+ isUserSelected,
3456
+ filterOptions,
3457
+ filteredUserGroup
3458
+ };
3459
+ };
3460
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3210
3461
  ...{
3211
3462
  name: "MeTag"
3212
3463
  },
3213
3464
  __name: "me-tag",
3214
3465
  props: {
3215
- /**
3216
- * 当前用户ID
3217
- */
3218
- currentUserId: {
3219
- type: String,
3220
- default: ""
3221
- },
3222
- /**
3223
- * 是否禁用
3224
- */
3225
- isDisabled: {
3226
- type: Boolean,
3227
- default: false
3228
- }
3466
+ currentUserId: { default: "" },
3467
+ isDisabled: { type: Boolean, default: false }
3229
3468
  },
3230
3469
  emits: ["click"],
3231
3470
  setup(__props, { emit: __emit }) {
@@ -3237,11 +3476,11 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3237
3476
  emit("click");
3238
3477
  };
3239
3478
  return (_ctx, _cache) => {
3240
- return __props.currentUserId ? (openBlock(), createElementBlock(
3479
+ return _ctx.currentUserId ? (openBlock(), createElementBlock(
3241
3480
  "div",
3242
3481
  {
3243
3482
  key: 0,
3244
- class: normalizeClass(["me-tag", { disabled: __props.isDisabled }]),
3483
+ class: normalizeClass(["me-tag", { disabled: _ctx.isDisabled }]),
3245
3484
  onClick: withModifiers(handleClick, ["stop"])
3246
3485
  },
3247
3486
  toDisplayString(unref(t)("我")),
@@ -3258,7 +3497,10 @@ const _export_sfc = (sfc, props) => {
3258
3497
  }
3259
3498
  return target;
3260
3499
  };
3261
- const MeTag = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-ef4a05c4"]]);
3500
+ const MeTag = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-4f251ce1"]]);
3501
+ const VirtualAvatar = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20width='32px'%20height='32px'%20viewBox='0%200%2032%2032'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%3e%3ctitle%3eIcon/虚拟icon%3c/title%3e%3cg%20id='Icon/虚拟icon'%20stroke='none'%20stroke-width='1'%20fill='none'%20fill-rule='evenodd'%3e%3cpath%20d='M27.4705882,3%20C28.315259,3%2029,3.68474098%2029,4.52941178%20L29,22.4623054%20C29,23.3069762%2028.315259,23.9917172%2027.4705882,23.9917172%20L20.5882353,23.9917172%20L20.5882353,27.0244081%20L24.0294118,27.0244081%20C24.2405794,27.0244081%2024.4117647,27.1955933%2024.4117647,27.406761%20L24.4117647,28.617647%20C24.4117647,28.8288148%2024.2405795,29%2024.0294118,29%20L7.97058824,29%20C7.75942054,29%207.58823529,28.8288148%207.58823529,28.617647%20L7.58823529,27.406761%20C7.58823531,27.1955933%207.75942055,27.0244081%207.97058824,27.0244081%20L11.4117647,27.0244081%20L11.4117647,23.9917172%20L4.52941178,23.9917172%20C3.68474098,23.9917172%203,23.3069762%203,22.4623054%20L3,4.52941178%20C3,3.68474098%203.68474098,3%204.52941178,3%20L27.4705882,3%20Z%20M19,24%20L13,24%20L13,27%20L19,27%20L19,24%20Z%20M23.4117647,7%20L8.58823529,7%20C8.03595054,7%207.58823529,7.44771525%207.58823529,8%20L7.58823529,19%20C7.58823529,19.5522847%208.03595054,20%208.58823529,20%20L23.4117647,20%20C23.9640495,20%2024.4117647,19.5522847%2024.4117647,19%20L24.4117647,8%20C24.4117647,7.44771525%2023.9640495,7%2023.4117647,7%20Z%20M12,10%20C12.5522847,10%2013,10.4477153%2013,11%20L13,13%20C13,13.5522847%2012.5522847,14%2012,14%20C11.4477153,14%2011,13.5522847%2011,13%20L11,11%20C11,10.4477153%2011.4477153,10%2012,10%20Z%20M20,10%20C20.5522847,10%2021,10.4477153%2021,11%20L21,13%20C21,13.5522847%2020.5522847,14%2020,14%20C19.4477153,14%2019,13.5522847%2019,13%20L19,11%20C19,10.4477153%2019.4477153,10%2020,10%20Z%20M26,5%20C25.4477153,5%2025,5.44771525%2025,6%20C25,6.55228475%2025.4477153,7%2026,7%20C26.5522847,7%2027,6.55228475%2027,6%20C27,5.44771525%2026.5522847,5%2026,5%20Z'%20id='蒙版'%20fill='%23A3C5FD'%20fill-rule='nonzero'%3e%3c/path%3e%3c/g%3e%3c/svg%3e";
3502
+ const UserGroupAvatar = "data:image/svg+xml,%3csvg%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20style='fill:%20%23A3C5FD;'%3e%3cpath%20fill-rule='evenodd'%20d='M405.7858816%20162.66256256C416.4461344%20160.6535248%20439.8986944%20159.44810208%20457.3815104%20160.25171712%20484.2453504%20161.05533248%20494.052784%20163.4661776%20516.226112%20174.7167888%20567.8217376%20200.43247136%20597.670448%20242.22045568%20606.6250624%20301.28616416%20617.711728%20374.415136%20593.4063488%20443.5260352%20535.8409792%20500.180896%20509.8299584%20525.8965792%20505.565856%20537.5489984%20514.0940608%20557.237568%20521.3430336%20572.9080608%20546.0748224%20586.5695168%20629.2248%20620.3213504%20691.054272%20645.2334208%20760.985536%20687.4232096%20767.8080992%20703.8973216%20774.6306624%20720.3714304%20784.8645056%20752.114224%20791.6870688%20777.4280992%20799.7888608%20807.1618592%20793.3927072%20818.8142784%20761.8383584%20832.4757344%20720.4765728%20850.155264%20669.3073536%20857.3878016%20546.9276416%20862.2094912%20392.9935776%20868.2366048%20227.12002944%20858.5932224%20162.30568672%20840.1100768%20134.5890272%20832.4757344%20108.15159776%20815.1980096%20100.47621504%20799.5275136%2093.6536528%20786.2678656%2094.08006304%20784.2588288%20105.59313696%20746.4889184%20116.67980096%20709.924432%20119.23826176%20705.5045504%20141.41158944%20685.4141728%20143.84821888%20683.2001312%20146.05397248%20681.2036448%20148.2232096%20679.3252416L152.13038144%20676.0501632C159.5946992%20670.0236288%20167.98497088%20664.6722176%20184.94031712%20656.0863296L191.29263904%20652.915344C215.97973152%20640.7492736%20256.51622304%20622.3959904%20329.458464%20589.3821696%20359.7335872%20575.3189056%20371.2466592%20563.6664896%20375.084352%20542.772496%20377.2164032%20530.316464%20374.6579424%20526.7001952%20345.2356416%20496.9664352%20295.34565344%20446.338688%20274.02514592%20396.9163584%20273.59873568%20331.0199232%20273.59873568%20291.24097568%20282.12693888%20265.52529312%20307.71154784%20228.15719168%20332.8697472%20191.19089792%20365.703328%20169.49329056%20405.7858816%20162.66256256ZM668.7713728%20226.60405184C756.683056%20211.50282816%20820.4190272%20263.09867616%20827.0124032%20354.9644544%20831.8475456%20416.6277856%20815.1443264%20461.931456%20770.3093664%20510.1714752%20752.287472%20529.4674848%20747.891888%20536.5986176%20748.3314464%20548.344016%20748.7710048%20555.8946272%20751.4083552%20565.123152%20754.485264%20568.8984576%20757.5621728%20572.2542848%20788.331264%20588.1944672%20823.0563776%20604.1346464%20944.3745024%20659.92528%20966.791984%20682.996592%20958.4403712%20744.6599232%20954.923904%20771.9260224%20956.6821376%20771.0870656%20890.308816%20787.0272448%20867.4517792%20792.8999456%20845.0343008%20798.3531648%20841.0782752%20799.6116%20835.3640128%20801.2895136%20833.1662208%20797.9336864%20830.5288704%20781.5740256%20824.3750528%20739.6261824%20812.0674176%20710.6821696%20790.0894976%20687.6108576%20752.287472%20647.3409248%20703.9360448%20619.6553504%20624.3759712%20593.6476864%20597.5629088%20584.4191616%20560.64%20550.8608864%20560.64%20534.920704%20560.64%20527.7895712%20569.8707264%20514.7857408%20589.6508544%20494.6507744%20620.859504%20461.931456%20639.7605152%20429.631616%20648.5516832%20394.8149056%20655.5846208%20366.7098496%20652.0681504%20283.23364096%20642.837424%20254.7091072%20635.3649312%20231.63779328%20634.4858144%20232.47675008%20668.7713728%20226.60405184Z'%3e%3c/path%3e%3c/svg%3e";
3503
+ const UserAvatar = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20width='32px'%20height='32px'%20viewBox='0%200%2032%2032'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%3e%3ctitle%3eIcon/用户%3c/title%3e%3cg%20id='Icon/用户'%20stroke='none'%20stroke-width='1'%20fill='none'%20fill-rule='evenodd'%3e%3cg%20id='user-(1)'%20transform='translate(3,%202)'%20fill='%23A3C5FD'%20fill-rule='nonzero'%3e%3cpath%20d='M13.0077612,27.9989067%20C10.3002732,27.9989067%207.59285518,28.0018792%204.88515705,27.997455%20C3.95018807,27.9959342%203.05044678,27.8282323%202.22816433,27.3628696%20C0.998627601,26.6672451%200.29953695,25.6114692%200.0864200465,24.2387462%20C-0.0656962495,23.259079%200.0147040645,22.4675755%200.0874005263,21.4879775%20C0.187970957,20.13461%200.423078914,19.3321844%200.863249688,18.0430358%20C1.22365046,16.9873982%201.73014453,16.0067633%202.49702917,15.175719%20C3.42254341,14.1726178%204.6014447,13.7297906%205.9255989,13.6440041%20C6.33292322,13.6073668%206.66741099,13.712025%206.9979768,13.9263185%20C7.58886318,14.3094892%208.17393665,14.7060014%208.79220674,15.0421658%20C10.1097776,15.758321%2011.5447274,16.1099698%2013.0616182,16.0930337%20C14.6806203,16.0750607%2016.2142496,15.63963%2017.592821,14.8169502%20C18.0555431,14.5407189%2018.5150436,14.256538%2018.9569652,13.9491996%20C19.3610679,13.6681294%2019.7808585,13.5749462%2020.274326,13.6337733%20C21.462472,13.7340074%2022.3872158,14.1103345%2023.2340106,14.8851094%20C23.902636,15.496952%2024.3685096,16.2520257%2024.7518119,17.0611566%20C25.272453,18.1598604%2025.5462904,18.7976948%2025.7441396,19.9861253%20C25.9499728,21.2233595%2026.0256808,22.2792045%2025.9924842,23.5308171%20C25.9627193,24.6543374%2025.6405577,25.6840525%2024.8535729,26.5307194%20C24.1686994,27.2671979%2023.3129402,27.7090574%2022.3211027,27.8808379%20C21.9232331,27.9495501%2021.5154185,27.9922014%2021.1120162,27.9935148%20C18.4104811,28.0036073%2015.7090862,27.9989067%2013.0077612,27.9989067%20L13.0077612,27.9989067%20Z%20M5.91775495,6.98479749%20C5.84814002,3.25685016%209.08684454,-0.00255470186%2013.0162355,1.5025268e-06%20C16.9117994,0.00256071584%2020.1304739,3.23452217%2020.1095656,7.04113598%20C20.0884528,10.8082092%2016.8998935,14.015354%2013.0058002,14.0149393%20C9.10134181,14.0145245%205.83322254,10.7695672%205.91775495,6.98479749%20Z'%20id='形状'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
3262
3504
  const UserRender = defineComponent({
3263
3505
  name: "UserRender",
3264
3506
  props: {
@@ -3277,23 +3519,63 @@ const UserRender = defineComponent({
3277
3519
  render: {
3278
3520
  type: Function,
3279
3521
  required: false
3522
+ },
3523
+ hasAvatar: {
3524
+ type: Boolean,
3525
+ default: false
3526
+ },
3527
+ avatarBaseUrl: {
3528
+ type: String,
3529
+ default: ""
3280
3530
  }
3281
3531
  },
3282
3532
  setup(props) {
3533
+ const getAvatarUrl = (user) => {
3534
+ if (user.type === "virtual") {
3535
+ return VirtualAvatar;
3536
+ }
3537
+ if (user.type === "userGroup") {
3538
+ return UserGroupAvatar;
3539
+ }
3540
+ if (!props.avatarBaseUrl) {
3541
+ return UserAvatar;
3542
+ }
3543
+ const loginName = user.login_name || user.bk_username || user.id;
3544
+ return `${props.avatarBaseUrl}${loginName}.png?default_when_absent=true`;
3545
+ };
3283
3546
  const defaultRender = (h2, props2) => {
3284
- return h2("div", [
3285
- h2("span", props2.user.name),
3286
- props2.user.tenantId !== props2.tenantId && props2.user.tenantId ? h2(
3287
- "span",
3288
- {
3547
+ return h2(
3548
+ "div",
3549
+ {
3550
+ style: {
3551
+ display: "flex",
3552
+ alignItems: "center"
3553
+ }
3554
+ },
3555
+ [
3556
+ props2.hasAvatar ? h2("img", {
3557
+ src: getAvatarUrl(props2.user),
3289
3558
  style: {
3290
- color: "#f59500",
3291
- marginLeft: "4px"
3559
+ width: "20px",
3560
+ height: "20px",
3561
+ borderRadius: "50%",
3562
+ marginRight: "6px",
3563
+ flexShrink: 0
3292
3564
  }
3293
- },
3294
- `@${props2.tenants[props2.user.tenantId] || props2.user.tenantId}`
3295
- ) : null
3296
- ]);
3565
+ }) : null,
3566
+ h2("span", props2.user.name),
3567
+ props2.user.tenantId !== props2.tenantId && props2.user.tenantId ? h2(
3568
+ "span",
3569
+ {
3570
+ style: {
3571
+ color: "#f59500",
3572
+ marginLeft: "4px"
3573
+ }
3574
+ },
3575
+ `@${props2.tenants[props2.user.tenantId] || props2.user.tenantId}`
3576
+ ) : null
3577
+ ]
3578
+ );
3297
3579
  };
3298
3580
  return () => {
3299
3581
  try {
@@ -3305,106 +3587,38 @@ const UserRender = defineComponent({
3305
3587
  };
3306
3588
  }
3307
3589
  });
3308
- const _hoisted_1$2 = {
3590
+ const _hoisted_1$1 = {
3309
3591
  key: 0,
3310
3592
  class: "no-data"
3311
3593
  };
3312
- const _hoisted_2$2 = { class: "group-name" };
3594
+ const _hoisted_2$1 = { class: "group-name" };
3313
3595
  const _hoisted_3$1 = { class: "group-count" };
3314
- const _hoisted_4$1 = ["onClick"];
3315
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
3596
+ const _hoisted_4 = ["onClick"];
3597
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3316
3598
  ...{
3317
3599
  name: "SelectionPopover"
3318
3600
  },
3319
3601
  __name: "selection-popover",
3320
3602
  props: {
3321
- /**
3322
- * 是否显示下拉菜单
3323
- */
3324
- isShow: {
3325
- type: Boolean,
3326
- default: false
3327
- },
3328
- /**
3329
- * 容器宽度
3330
- */
3331
- containerWidth: {
3332
- type: [Number, String],
3333
- default: "auto"
3334
- },
3335
- /**
3336
- * popover crossAxis 偏移量
3337
- */
3338
- crossAxisOffset: {
3339
- type: Number,
3340
- default: 0
3341
- },
3342
- /**
3343
- * 是否加载中
3344
- */
3345
- loading: {
3346
- type: Boolean,
3347
- default: false
3348
- },
3349
- /**
3350
- * 搜索结果选项
3351
- */
3352
- options: {
3353
- type: Array,
3354
- default: () => []
3355
- },
3356
- /**
3357
- * 搜索关键词
3358
- */
3359
- searchQuery: {
3360
- type: String,
3361
- default: ""
3362
- },
3363
- /**
3364
- * 当前租户ID
3365
- */
3366
- tenantId: {
3367
- type: String,
3368
- default: ""
3369
- },
3370
- /**
3371
- * 租户信息映射
3372
- */
3373
- tenants: {
3374
- type: Object,
3375
- default: () => ({})
3376
- },
3377
- /**
3378
- * 用户组
3379
- */
3380
- userGroup: {
3381
- type: Array,
3382
- default: () => []
3383
- },
3384
- /**
3385
- * 用户组名称
3386
- */
3387
- userGroupName: {
3388
- type: String,
3389
- default: ""
3390
- },
3391
- /**
3392
- * 无匹配人员时的提示文本
3393
- */
3394
- emptyText: {
3395
- type: String,
3396
- default: ""
3397
- },
3398
- /**
3399
- * 渲染列表项
3400
- */
3401
- renderListItem: {
3402
- type: Function
3403
- }
3603
+ avatarBaseUrl: { default: "" },
3604
+ containerWidth: { default: "auto" },
3605
+ emptyText: { default: "" },
3606
+ hasAvatar: { type: Boolean, default: false },
3607
+ isShow: { type: Boolean, default: false },
3608
+ loading: { type: Boolean, default: false },
3609
+ options: { default: () => [] },
3610
+ renderListItem: {},
3611
+ searchQuery: { default: "" },
3612
+ tenantId: { default: "" },
3613
+ tenants: { default: () => ({}) },
3614
+ userGroup: { default: () => [] },
3615
+ userGroupName: { default: "" }
3404
3616
  },
3405
- emits: ["select-user", "click-outside"],
3617
+ emits: ["click-outside", "select-user"],
3406
3618
  setup(__props, { emit: __emit }) {
3407
3619
  const { t } = useI18n();
3620
+ const slotContainerRef = ref(null);
3621
+ const contentContainerRef = ref(null);
3408
3622
  const props = __props;
3409
3623
  const emit = __emit;
3410
3624
  const groupedUsers = computed(() => {
@@ -3413,11 +3627,11 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
3413
3627
  groups[props.userGroupName] = props.userGroup.map((group) => ({
3414
3628
  ...group,
3415
3629
  tenantId: "",
3416
- type: "userGroup"
3630
+ type: USER_TYPE.USER_GROUP
3417
3631
  }));
3418
3632
  }
3419
3633
  props.options.forEach((user) => {
3420
- const groupName = user.data_source_type === "virtual" ? t("虚拟账号") : t("用户");
3634
+ const groupName = user.data_source_type === USER_TYPE.VIRTUAL ? t("虚拟账号") : t("用户");
3421
3635
  if (!groups[groupName]) {
3422
3636
  groups[groupName] = [];
3423
3637
  }
@@ -3429,114 +3643,150 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
3429
3643
  emit("select-user", user);
3430
3644
  };
3431
3645
  const handleClickOutside = ({ event }) => {
3646
+ var _a, _b;
3647
+ const target = event.target;
3648
+ if ((_a = slotContainerRef.value) == null ? void 0 : _a.contains(target)) {
3649
+ return;
3650
+ }
3651
+ if ((_b = contentContainerRef.value) == null ? void 0 : _b.contains(target)) {
3652
+ return;
3653
+ }
3432
3654
  emit("click-outside", event);
3433
3655
  };
3434
3656
  return (_ctx, _cache) => {
3435
3657
  return openBlock(), createBlock(unref(Popover), {
3436
3658
  arrow: false,
3437
3659
  "ext-cls": "bk-user-selector-popover",
3438
- "is-show": __props.isShow,
3439
- offset: { mainAxis: 4, crossAxis: __props.crossAxisOffset },
3660
+ "is-show": _ctx.isShow,
3661
+ offset: { mainAxis: 4 },
3440
3662
  placement: "bottom-start",
3441
3663
  theme: "light",
3442
3664
  trigger: "manual",
3443
- width: __props.containerWidth,
3665
+ width: _ctx.containerWidth,
3444
3666
  onClickoutside: handleClickOutside
3445
3667
  }, {
3446
3668
  content: withCtx(() => [
3447
- createVNode(unref(Loading), {
3448
- class: "dropdown-content",
3449
- loading: __props.loading,
3450
- mode: "spin",
3451
- size: "mini"
3452
- }, {
3453
- default: withCtx(() => [
3454
- __props.options.length === 0 && __props.userGroup.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$2, [
3455
- createElementVNode(
3456
- "span",
3457
- null,
3458
- toDisplayString(__props.emptyText),
3459
- 1
3460
- /* TEXT */
3461
- )
3462
- ])) : (openBlock(true), createElementBlock(
3463
- Fragment,
3464
- { key: 1 },
3465
- renderList(groupedUsers.value, (group, groupName) => {
3466
- return openBlock(), createElementBlock("div", {
3467
- key: groupName,
3468
- class: "user-group"
3469
- }, [
3470
- Object.keys(groupedUsers.value).length > 1 || group.some((user) => user.type === "userGroup") ? (openBlock(), createElementBlock("div", {
3471
- key: 0,
3472
- class: "group-header",
3473
- onClick: _cache[0] || (_cache[0] = withModifiers(() => {
3474
- }, ["prevent"]))
3475
- }, [
3476
- createElementVNode(
3477
- "span",
3478
- _hoisted_2$2,
3479
- toDisplayString(groupName),
3480
- 1
3481
- /* TEXT */
3482
- ),
3483
- createElementVNode(
3484
- "span",
3485
- _hoisted_3$1,
3486
- "(" + toDisplayString(group.length) + ")",
3487
- 1
3488
- /* TEXT */
3489
- )
3490
- ])) : createCommentVNode("v-if", true),
3491
- (openBlock(true), createElementBlock(
3492
- Fragment,
3669
+ createElementVNode(
3670
+ "div",
3671
+ {
3672
+ ref_key: "contentContainerRef",
3673
+ ref: contentContainerRef
3674
+ },
3675
+ [
3676
+ createVNode(unref(Loading), {
3677
+ class: "dropdown-content",
3678
+ loading: _ctx.loading,
3679
+ mode: "spin",
3680
+ size: "mini"
3681
+ }, {
3682
+ default: withCtx(() => [
3683
+ _ctx.options.length === 0 && _ctx.userGroup.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
3684
+ createElementVNode(
3685
+ "span",
3493
3686
  null,
3494
- renderList(group, (user) => {
3495
- return openBlock(), createElementBlock("div", {
3496
- key: user.id,
3497
- class: "user-option",
3498
- onClick: withModifiers(($event) => selectUser(user), ["prevent"])
3687
+ toDisplayString(_ctx.emptyText),
3688
+ 1
3689
+ /* TEXT */
3690
+ )
3691
+ ])) : (openBlock(true), createElementBlock(
3692
+ Fragment,
3693
+ { key: 1 },
3694
+ renderList(groupedUsers.value, (group, groupName) => {
3695
+ return openBlock(), createElementBlock("div", {
3696
+ key: groupName,
3697
+ class: "user-group"
3698
+ }, [
3699
+ Object.keys(groupedUsers.value).length > 1 || group.some((user) => user.type === "userGroup") ? (openBlock(), createElementBlock("div", {
3700
+ key: 0,
3701
+ class: "group-header",
3702
+ onClick: _cache[0] || (_cache[0] = withModifiers(() => {
3703
+ }, ["prevent"]))
3499
3704
  }, [
3500
- createVNode(unref(UserRender), {
3501
- render: __props.renderListItem,
3502
- "tenant-id": __props.tenantId,
3503
- tenants: __props.tenants,
3504
- user
3505
- }, null, 8, ["render", "tenant-id", "tenants", "user"])
3506
- ], 8, _hoisted_4$1);
3507
- }),
3508
- 128
3509
- /* KEYED_FRAGMENT */
3510
- ))
3511
- ]);
3512
- }),
3513
- 128
3514
- /* KEYED_FRAGMENT */
3515
- ))
3516
- ]),
3517
- _: 1
3518
- /* STABLE */
3519
- }, 8, ["loading"])
3705
+ createElementVNode(
3706
+ "span",
3707
+ _hoisted_2$1,
3708
+ toDisplayString(groupName),
3709
+ 1
3710
+ /* TEXT */
3711
+ ),
3712
+ createElementVNode(
3713
+ "span",
3714
+ _hoisted_3$1,
3715
+ "(" + toDisplayString(group.length) + ")",
3716
+ 1
3717
+ /* TEXT */
3718
+ )
3719
+ ])) : createCommentVNode("v-if", true),
3720
+ (openBlock(true), createElementBlock(
3721
+ Fragment,
3722
+ null,
3723
+ renderList(group, (user) => {
3724
+ return openBlock(), createElementBlock("div", {
3725
+ key: user.id,
3726
+ class: "user-option",
3727
+ onClick: withModifiers(($event) => selectUser(user), ["prevent"]),
3728
+ onMousedown: _cache[1] || (_cache[1] = withModifiers(() => {
3729
+ }, ["prevent"]))
3730
+ }, [
3731
+ createVNode(unref(UserRender), {
3732
+ "avatar-base-url": _ctx.avatarBaseUrl,
3733
+ "has-avatar": _ctx.hasAvatar,
3734
+ render: _ctx.renderListItem,
3735
+ "tenant-id": _ctx.tenantId,
3736
+ tenants: _ctx.tenants,
3737
+ user
3738
+ }, null, 8, ["avatar-base-url", "has-avatar", "render", "tenant-id", "tenants", "user"])
3739
+ ], 40, _hoisted_4);
3740
+ }),
3741
+ 128
3742
+ /* KEYED_FRAGMENT */
3743
+ ))
3744
+ ]);
3745
+ }),
3746
+ 128
3747
+ /* KEYED_FRAGMENT */
3748
+ ))
3749
+ ]),
3750
+ _: 1
3751
+ /* STABLE */
3752
+ }, 8, ["loading"])
3753
+ ],
3754
+ 512
3755
+ /* NEED_PATCH */
3756
+ )
3520
3757
  ]),
3521
3758
  default: withCtx(() => [
3522
- renderSlot(_ctx.$slots, "default", {}, void 0, true)
3759
+ createElementVNode(
3760
+ "div",
3761
+ {
3762
+ ref_key: "slotContainerRef",
3763
+ ref: slotContainerRef
3764
+ },
3765
+ [
3766
+ renderSlot(_ctx.$slots, "default", {}, void 0, true)
3767
+ ],
3768
+ 512
3769
+ /* NEED_PATCH */
3770
+ )
3523
3771
  ]),
3524
3772
  _: 3
3525
3773
  /* FORWARDED */
3526
- }, 8, ["is-show", "offset", "width"]);
3774
+ }, 8, ["is-show", "width"]);
3527
3775
  };
3528
3776
  }
3529
3777
  });
3530
- const SelectionPopover = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-78875ea6"]]);
3531
- const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3778
+ const SelectionPopover = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-d5a338f0"]]);
3779
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
3532
3780
  ...{
3533
3781
  name: "UserTag"
3534
3782
  },
3535
3783
  __name: "user-tag",
3536
3784
  props: {
3537
3785
  active: { type: Boolean },
3786
+ avatarBaseUrl: {},
3538
3787
  currentTenantId: {},
3539
3788
  draggable: { type: Boolean },
3789
+ hasAvatar: { type: Boolean },
3540
3790
  renderTag: { type: Function },
3541
3791
  showTenant: { type: Boolean },
3542
3792
  tenants: {},
@@ -3561,11 +3811,13 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3561
3811
  }, {
3562
3812
  default: withCtx(() => [
3563
3813
  createVNode(unref(UserRender), {
3814
+ "avatar-base-url": _ctx.avatarBaseUrl,
3815
+ "has-avatar": _ctx.hasAvatar,
3564
3816
  render: _ctx.renderTag,
3565
3817
  "tenant-id": _ctx.currentTenantId,
3566
3818
  tenants: _ctx.tenants,
3567
3819
  user: _ctx.user
3568
- }, null, 8, ["render", "tenant-id", "tenants", "user"])
3820
+ }, null, 8, ["avatar-base-url", "has-avatar", "render", "tenant-id", "tenants", "user"])
3569
3821
  ]),
3570
3822
  _: 1
3571
3823
  /* STABLE */
@@ -3573,84 +3825,176 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3573
3825
  };
3574
3826
  }
3575
3827
  });
3576
- const UserTag = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-48ac8fc1"]]);
3577
- const _hoisted_1$1 = ["onClick"];
3578
- const _hoisted_2$1 = ["placeholder"];
3579
- const _hoisted_3 = { class: "hidden-users" };
3580
- const _hoisted_4 = ["placeholder"];
3581
- const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3828
+ const UserTag = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-1f2e0737"]]);
3829
+ const _hoisted_1 = ["placeholder"];
3830
+ const _hoisted_2 = { class: "hidden-users" };
3831
+ const _hoisted_3 = ["placeholder"];
3832
+ const _sfc_main = /* @__PURE__ */ defineComponent({
3582
3833
  ...{
3583
- name: "BkUserSelectorMultiple"
3834
+ name: "BkUserSelector"
3584
3835
  },
3585
- __name: "multiple-selector",
3836
+ __name: "user-selector",
3586
3837
  props: {
3587
3838
  draggable: { type: Boolean, default: false },
3588
- freePaste: { type: Boolean, default: false },
3589
- modelValue: { default: () => [] },
3590
- selectedUsers: { default: () => [] },
3591
- tenants: { default: () => ({}) },
3839
+ maxCount: { default: 0 },
3840
+ modelValue: { default: "" },
3841
+ multiple: { type: Boolean, default: false },
3592
3842
  allowCreate: { type: Boolean, default: false },
3593
3843
  apiBaseUrl: { default: "" },
3844
+ avatarBaseUrl: { default: "" },
3845
+ hasAvatar: { type: Boolean, default: false },
3594
3846
  currentUserId: { default: "" },
3595
- disabled: { type: Boolean },
3847
+ disabled: { type: Boolean, default: false },
3596
3848
  emptyText: { default: "" },
3597
- enableMultiTenantMode: { type: Boolean },
3598
- exactSearchKey: { default: "bk_username" },
3849
+ enableMultiTenantMode: { type: Boolean, default: true },
3850
+ exactSearchKey: { default: DEFAULT_EXACT_SEARCH_KEY },
3599
3851
  excludeUserIds: { default: () => [] },
3852
+ freePaste: { type: Boolean, default: false },
3600
3853
  placeholder: { default: "" },
3601
- tenantId: { default: "" },
3602
- userGroupName: { default: "" },
3603
3854
  renderListItem: {},
3604
3855
  renderTag: {},
3605
- userGroup: { default: () => [] }
3856
+ tenantId: { default: "" },
3857
+ userGroup: { default: () => [] },
3858
+ userGroupName: { default: "" }
3606
3859
  },
3607
- emits: [
3608
- "update:selectedUsers",
3609
- "add-user",
3610
- "remove-user",
3611
- "dragStart",
3612
- "dragEnd",
3613
- "focus",
3614
- "blur"
3615
- ],
3860
+ emits: ["blur", "change", "dragEnd", "dragStart", "focus", "update:modelValue"],
3616
3861
  setup(__props, { emit: __emit }) {
3862
+ const { t } = useI18n();
3863
+ provideGlobalConfig({
3864
+ prefix: "bk"
3865
+ });
3617
3866
  const props = __props;
3618
3867
  const emit = __emit;
3868
+ const { tenants = {} } = useTenantData(props.apiBaseUrl, props.tenantId, props.enableMultiTenantMode);
3619
3869
  const {
3620
3870
  searchResults,
3621
3871
  loading: searchLoading,
3622
3872
  searchQuery,
3623
- // clearSearch,
3873
+ clearSearch,
3624
3874
  handleSearchInput
3625
3875
  } = useUserSearch(props.apiBaseUrl, props.tenantId, props.enableMultiTenantMode);
3876
+ const { fetchCurrentUser } = useCurrentUser({
3877
+ apiBaseUrl: props.apiBaseUrl,
3878
+ tenantId: props.tenantId,
3879
+ currentUserId: props.currentUserId || "",
3880
+ exactSearchKey: props.exactSearchKey,
3881
+ enableMultiTenantMode: props.enableMultiTenantMode
3882
+ });
3626
3883
  const containerRef = ref(null);
3627
- const tagsContainerRef = ref(null);
3628
3884
  const sortableContainerRef = ref(null);
3629
3885
  const collapsedContainerRef = ref(null);
3630
3886
  const inlineInputRef = ref(null);
3631
3887
  const lastInputRef = ref(null);
3632
- const collapsedInputRef = ref(null);
3633
3888
  const isFocused = ref(false);
3634
- const showDropdown = ref(false);
3635
3889
  const activeTagIndex = ref(-1);
3636
3890
  const sortableInstance = ref(null);
3637
3891
  const visibleUsers = ref([]);
3638
3892
  const hiddenCount = ref(0);
3639
- const options = computed(() => {
3640
- return searchResults.value.filter((user) => !props.selectedUsers.some((selectedUser) => selectedUser.id === user.id)).filter((user) => !props.excludeUserIds.includes(user.id));
3893
+ const selectedUsers = ref([]);
3894
+ const showDropdown = computed(() => {
3895
+ return isFocused.value && (props.userGroup.length > 0 || searchQuery.value.trim() !== "");
3641
3896
  });
3642
- const userGroupFilter = computed(() => {
3643
- return props.userGroup.filter((group) => {
3644
- var _a, _b;
3645
- const filtered = !props.selectedUsers.some((user) => user.id === group.id) && !group.hidden;
3646
- if (filtered) {
3647
- return ((_a = group.id) == null ? void 0 : _a.includes(searchQuery.value)) || ((_b = group.name) == null ? void 0 : _b.includes(searchQuery.value));
3648
- }
3649
- return false;
3650
- });
3897
+ const modelValueIds = computed(() => {
3898
+ if (props.multiple) {
3899
+ return Array.isArray(props.modelValue) ? props.modelValue : [];
3900
+ }
3901
+ return props.modelValue ? [props.modelValue] : [];
3902
+ });
3903
+ const computedPlaceholder = computed(() => props.placeholder || t("请输入人员名称搜索"));
3904
+ const computedUserGroupName = computed(() => props.userGroupName || t("用户群组"));
3905
+ const computedEmptyText = computed(() => props.emptyText || t("无匹配人员"));
3906
+ const selectedUserIds = computed(() => selectedUsers.value.map((user) => user.id));
3907
+ const isMaxCountReached = computed(() => {
3908
+ if (!props.maxCount || props.maxCount <= 0) return false;
3909
+ return selectedUsers.value.length >= props.maxCount;
3910
+ });
3911
+ const isMeTagDisabled = computed(
3912
+ () => isMaxCountReached.value || !!props.currentUserId && selectedUsers.value.some((user) => user[props.exactSearchKey] === props.currentUserId)
3913
+ );
3914
+ const userTagCommonProps = computed(() => ({
3915
+ avatarBaseUrl: props.avatarBaseUrl,
3916
+ currentTenantId: props.tenantId,
3917
+ hasAvatar: props.hasAvatar,
3918
+ renderTag: props.renderTag,
3919
+ tenants
3920
+ }));
3921
+ const { filteredUserGroup, filterOptions, createCustomUser } = useUserSelection({
3922
+ selectedUserIds,
3923
+ excludeUserIds: toRef(props, "excludeUserIds"),
3924
+ userGroup: toRef(props, "userGroup"),
3925
+ searchQuery
3926
+ });
3927
+ const { handlePaste } = useInputHandler({
3928
+ apiBaseUrl: props.apiBaseUrl,
3929
+ tenantId: props.tenantId,
3930
+ searchQuery,
3931
+ selectedUsers,
3932
+ allowCreate: props.allowCreate,
3933
+ freePaste: props.freePaste,
3934
+ enableMultiTenantMode: props.enableMultiTenantMode,
3935
+ maxCount: props.maxCount,
3936
+ onAddUser: addUser,
3937
+ onBatchAddUsers: props.multiple ? updateSelectedUsers : void 0
3938
+ });
3939
+ const displayOptions = computed(() => filterOptions(searchResults.value));
3940
+ const inputWidth = computed(() => {
3941
+ const query = searchQuery.value;
3942
+ if (!query) return "20px";
3943
+ const charWidth = query.split("").reduce((acc, char) => {
3944
+ return acc + (/[\u4e00-\u9fa5]/.test(char) ? 12 : 8);
3945
+ }, 0);
3946
+ return `${Math.max(20, charWidth + 4)}px`;
3651
3947
  });
3948
+ const initSelectedUsers = async () => {
3949
+ const ids = modelValueIds.value;
3950
+ if (ids.length === 0) {
3951
+ selectedUsers.value = [];
3952
+ return;
3953
+ }
3954
+ let userGroupSelected = [];
3955
+ if (props.userGroup.length > 0) {
3956
+ const result = props.userGroup.filter((group) => ids.includes(group.id));
3957
+ userGroupSelected = result.map((group) => ({
3958
+ ...group,
3959
+ tenantId: "",
3960
+ type: USER_TYPE.USER_GROUP
3961
+ }));
3962
+ }
3963
+ try {
3964
+ const result = await lookupUsers({
3965
+ apiBaseUrl: props.apiBaseUrl,
3966
+ tenantId: props.tenantId,
3967
+ exactSearchKey: "bk_username",
3968
+ usersList: ids,
3969
+ enableMultiTenantMode: props.enableMultiTenantMode
3970
+ });
3971
+ const selectedList = [...userGroupSelected, ...formatUsers(result, props.enableMultiTenantMode)];
3972
+ if (props.allowCreate) {
3973
+ selectedList.push(
3974
+ ...ids.filter((id) => !selectedList.some((user) => user.id === id)).map((id) => ({ id, name: id, type: USER_TYPE.CUSTOM, tenantId: "" }))
3975
+ );
3976
+ }
3977
+ selectedUsers.value = ids.map((id) => selectedList.find((user) => user.id === id)).filter(Boolean);
3978
+ } catch (error) {
3979
+ console.error("获取选中用户信息失败:", error);
3980
+ selectedUsers.value = [];
3981
+ }
3982
+ };
3983
+ function updateSelectedUsers(users) {
3984
+ selectedUsers.value = users;
3985
+ if (props.multiple) {
3986
+ const ids = users.map((user) => user.id);
3987
+ emit("update:modelValue", ids);
3988
+ emit("change", users);
3989
+ } else {
3990
+ const user = users.length > 0 ? users[0] : null;
3991
+ const id = user ? user.id : "";
3992
+ emit("update:modelValue", id);
3993
+ emit("change", user);
3994
+ }
3995
+ }
3652
3996
  const initSortable = () => {
3653
- if (!props.draggable || !sortableContainerRef.value) return;
3997
+ if (!props.draggable || !props.multiple || !sortableContainerRef.value) return;
3654
3998
  if (sortableInstance.value) {
3655
3999
  sortableInstance.value.destroy();
3656
4000
  }
@@ -3663,276 +4007,206 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3663
4007
  onEnd: (evt) => {
3664
4008
  const { oldIndex, newIndex } = evt;
3665
4009
  if (oldIndex === newIndex || oldIndex === void 0 || newIndex === void 0) return;
3666
- const updatedUsers = [...props.selectedUsers];
4010
+ const updatedUsers = [...selectedUsers.value];
3667
4011
  const [movedUser] = updatedUsers.splice(oldIndex, 1);
3668
4012
  updatedUsers.splice(newIndex, 0, movedUser);
3669
- emit("update:selectedUsers", updatedUsers);
4013
+ updateSelectedUsers(updatedUsers);
3670
4014
  emit("dragEnd", evt);
3671
4015
  }
3672
4016
  });
3673
4017
  };
3674
4018
  const calculateVisibleUsers = () => {
3675
- if (!collapsedContainerRef.value || !props.selectedUsers.length) {
4019
+ if (!selectedUsers.value.length) {
3676
4020
  visibleUsers.value = [];
3677
4021
  hiddenCount.value = 0;
3678
4022
  return;
3679
4023
  }
4024
+ if (!collapsedContainerRef.value) {
4025
+ visibleUsers.value = [...selectedUsers.value];
4026
+ hiddenCount.value = 0;
4027
+ return;
4028
+ }
3680
4029
  const containerWidth = collapsedContainerRef.value.offsetWidth;
3681
4030
  const tagElements = collapsedContainerRef.value.querySelectorAll(".user-tag");
4031
+ if (tagElements.length !== selectedUsers.value.length) {
4032
+ visibleUsers.value = [...selectedUsers.value];
4033
+ hiddenCount.value = 0;
4034
+ nextTick(calculateVisibleUsers);
4035
+ return;
4036
+ }
3682
4037
  const visibleCount = calculateVisibleTags(
3683
4038
  collapsedContainerRef.value,
3684
4039
  tagElements,
3685
- containerWidth - 100
3686
- // 为输入框和更多标签预留空间
4040
+ containerWidth - RESERVED_SPACE_FOR_INPUT
3687
4041
  );
3688
- visibleUsers.value = props.selectedUsers.slice(0, visibleCount);
3689
- hiddenCount.value = Math.max(0, props.selectedUsers.length - visibleCount);
4042
+ visibleUsers.value = selectedUsers.value.slice(0, visibleCount);
4043
+ hiddenCount.value = Math.max(0, selectedUsers.value.length - visibleCount);
3690
4044
  };
3691
4045
  const handleFocus = () => {
3692
4046
  isFocused.value = true;
3693
- if (props.userGroup.length > 0) {
3694
- showDropdown.value = true;
3695
- } else {
3696
- showDropdown.value = false;
3697
- }
3698
4047
  activeTagIndex.value = -1;
3699
4048
  nextTick(() => {
3700
- if (lastInputRef.value) {
3701
- lastInputRef.value.focus();
3702
- }
4049
+ var _a;
4050
+ return (_a = lastInputRef.value) == null ? void 0 : _a.focus();
3703
4051
  });
3704
4052
  };
4053
+ const scheduleVisibleUsersCalculation = () => {
4054
+ if (!isFocused.value) {
4055
+ nextTick(calculateVisibleUsers);
4056
+ }
4057
+ };
3705
4058
  const handleClickOutside = (event) => {
3706
4059
  const target = event.target;
3707
4060
  const container = containerRef.value;
3708
- if ((container == null ? void 0 : container.contains(target)) || container === target) {
3709
- return;
3710
- }
3711
- if (isFocused.value) {
3712
- emit("blur");
3713
- }
4061
+ if ((container == null ? void 0 : container.contains(target)) || container === target) return;
4062
+ if (isFocused.value) emit("blur");
3714
4063
  isFocused.value = false;
3715
- showDropdown.value = false;
3716
4064
  activeTagIndex.value = -1;
3717
- searchQuery.value = "";
3718
- nextTick(() => {
3719
- calculateVisibleUsers();
3720
- });
4065
+ clearSearch();
4066
+ scheduleVisibleUsersCalculation();
3721
4067
  };
3722
4068
  const handleContainerClick = () => {
3723
4069
  activeTagIndex.value = -1;
3724
4070
  nextTick(() => {
3725
- if (lastInputRef.value) {
3726
- lastInputRef.value.focus();
3727
- }
4071
+ var _a;
4072
+ return (_a = lastInputRef.value) == null ? void 0 : _a.focus();
3728
4073
  });
3729
4074
  };
3730
4075
  const handleTagClick = (index) => {
3731
4076
  activeTagIndex.value = index;
3732
4077
  nextTick(() => {
3733
4078
  var _a;
3734
- if (activeTagIndex.value === props.selectedUsers.length - 1) {
3735
- if (lastInputRef.value) {
3736
- lastInputRef.value.focus();
3737
- }
3738
- } else if ((_a = inlineInputRef.value) == null ? void 0 : _a[0]) {
3739
- inlineInputRef.value[0].focus();
3740
- }
4079
+ const isLastTag = index === selectedUsers.value.length - 1;
4080
+ const targetInput = isLastTag ? lastInputRef.value : (_a = inlineInputRef.value) == null ? void 0 : _a[0];
4081
+ targetInput == null ? void 0 : targetInput.focus();
3741
4082
  });
3742
4083
  };
3743
4084
  const handleInputFocus = () => {
3744
4085
  emit("focus");
3745
- if (!isFocused.value) {
3746
- isFocused.value = true;
3747
- }
3748
- if (searchQuery.value.length >= 1) {
3749
- showDropdown.value = true;
3750
- }
4086
+ isFocused.value = true;
3751
4087
  };
3752
4088
  const handleInput = () => {
3753
4089
  handleSearchInput(searchQuery.value);
3754
- if (searchQuery.value.length >= 1) {
3755
- showDropdown.value = true;
3756
- } else {
3757
- showDropdown.value = false;
3758
- }
3759
4090
  };
3760
4091
  const addCurrentUser = async () => {
3761
- if (!props.currentUserId || props.selectedUsers.some((user) => user.id === props.currentUserId)) return;
3762
- try {
3763
- const result = await lookupUsers({
3764
- apiBaseUrl: props.apiBaseUrl,
3765
- tenantId: props.tenantId,
3766
- exactSearchKey: props.exactSearchKey,
3767
- usersList: [props.currentUserId],
3768
- enableMultiTenantMode: props.enableMultiTenantMode
3769
- });
3770
- const formattedUsers = formatUsers(result, props.enableMultiTenantMode);
3771
- if (formattedUsers.length > 0) {
3772
- if (!props.selectedUsers.some((item) => item.id === formattedUsers[0].id)) {
3773
- emit("update:selectedUsers", [...props.selectedUsers, formattedUsers[0]]);
3774
- emit("add-user", formattedUsers[0]);
3775
- }
3776
- searchQuery.value = "";
3777
- showDropdown.value = false;
3778
- }
3779
- } catch (error) {
3780
- console.error("获取当前用户信息失败:", error);
4092
+ if (!props.currentUserId || selectedUsers.value.some((user) => user[props.exactSearchKey] === props.currentUserId))
4093
+ return;
4094
+ if (props.multiple && isMaxCountReached.value) {
4095
+ return;
3781
4096
  }
3782
- };
3783
- const handlePaste = async (event) => {
3784
- var _a;
3785
- event.preventDefault();
3786
- const pastedText = ((_a = event.clipboardData) == null ? void 0 : _a.getData("text")) || "";
3787
- if (pastedText.trim()) {
3788
- try {
3789
- const usersList = pastedText.trim().split(/[,,;\n\s]+/).filter(Boolean);
3790
- const users = usersList.map((user) => user.trim().replace(/\s*\(.*?\)\s*/, "")).filter((user) => user);
3791
- const result = await lookupUsers({
3792
- apiBaseUrl: props.apiBaseUrl,
3793
- tenantId: props.tenantId,
3794
- exactSearchKey: "login_name",
3795
- usersList: users,
3796
- enableMultiTenantMode: props.enableMultiTenantMode
3797
- });
3798
- const formattedUsers = formatUsers(result, props.enableMultiTenantMode);
3799
- if (formattedUsers.length > 0) {
3800
- const userMap = /* @__PURE__ */ new Map();
3801
- [...props.selectedUsers, ...formattedUsers].forEach((user) => {
3802
- if (!userMap.has(user.id)) {
3803
- userMap.set(user.id, user);
3804
- }
3805
- });
3806
- const updatedUsers = Array.from(userMap.values());
3807
- if (props.freePaste) {
3808
- const pastedUsers = usersList.map((user) => ({
3809
- id: user,
3810
- name: user,
3811
- type: "custom",
3812
- tenantId: "",
3813
- login_name: user
3814
- }));
3815
- pastedUsers.forEach((user) => {
3816
- if (!updatedUsers.some((item) => item.login_name === user.login_name)) {
3817
- addUser(user);
3818
- }
3819
- });
3820
- } else {
3821
- emit("update:selectedUsers", updatedUsers);
3822
- }
3823
- } else {
3824
- if (props.freePaste) {
3825
- const pastedUsers = usersList.map((user) => ({
3826
- id: user,
3827
- name: user,
3828
- type: "custom",
3829
- tenantId: "",
3830
- login_name: user
3831
- }));
3832
- pastedUsers.forEach((user) => {
3833
- if (!props.selectedUsers.some((item) => item.login_name === user.login_name)) {
3834
- addUser(user);
3835
- }
3836
- });
3837
- }
3838
- }
3839
- } catch (error) {
3840
- console.error("精准查找用户失败:", error);
4097
+ const currentUser = await fetchCurrentUser();
4098
+ if (currentUser) {
4099
+ if (!props.multiple) {
4100
+ updateSelectedUsers([currentUser]);
4101
+ } else if (!selectedUsers.value.some((item) => item.id === currentUser.id)) {
4102
+ updateSelectedUsers([...selectedUsers.value, currentUser]);
3841
4103
  }
4104
+ clearSearch();
4105
+ isFocused.value = true;
4106
+ nextTick(() => {
4107
+ var _a;
4108
+ return (_a = lastInputRef.value) == null ? void 0 : _a.focus();
4109
+ });
3842
4110
  }
3843
4111
  };
4112
+ const onPaste = (event) => {
4113
+ handlePaste(event);
4114
+ };
3844
4115
  const handleKeyDown = (event) => {
3845
- if (event.key === "Backspace" && !searchQuery.value && props.selectedUsers.length > 0) {
4116
+ if (event.key === "Backspace" && !searchQuery.value && selectedUsers.value.length > 0) {
3846
4117
  if (activeTagIndex.value >= 0) {
3847
- const userToRemove = props.selectedUsers[activeTagIndex.value];
4118
+ const userToRemove = selectedUsers.value[activeTagIndex.value];
3848
4119
  removeUser(userToRemove);
3849
- if (activeTagIndex.value > 0) {
3850
- activeTagIndex.value = activeTagIndex.value - 1;
3851
- } else {
3852
- activeTagIndex.value = -1;
3853
- }
4120
+ activeTagIndex.value = activeTagIndex.value > 0 ? activeTagIndex.value - 1 : -1;
3854
4121
  } else {
3855
- const lastUser = props.selectedUsers[props.selectedUsers.length - 1];
4122
+ const lastUser = selectedUsers.value[selectedUsers.value.length - 1];
3856
4123
  removeUser(lastUser);
3857
4124
  }
3858
- } else if (event.key === "Enter" && props.allowCreate) {
3859
- addUser({
3860
- id: searchQuery.value,
3861
- name: searchQuery.value,
3862
- type: "custom",
3863
- tenantId: "",
3864
- login_name: searchQuery.value
3865
- });
4125
+ } else if (event.key === "Enter" && props.allowCreate && searchQuery.value) {
4126
+ addUser(createCustomUser(searchQuery.value));
3866
4127
  }
3867
4128
  };
3868
- const addUser = (user) => {
4129
+ function addUser(user) {
3869
4130
  if (!(user == null ? void 0 : user.id)) return;
3870
- if (!props.selectedUsers.some((item) => item.id === user.id)) {
4131
+ if (props.multiple && isMaxCountReached.value) {
4132
+ clearSearch();
4133
+ return;
4134
+ }
4135
+ if (!props.multiple) {
4136
+ updateSelectedUsers([user]);
4137
+ } else if (!selectedUsers.value.some((item) => item.id === user.id)) {
4138
+ const updatedUsers = activeTagIndex.value !== -1 ? [
4139
+ ...selectedUsers.value.slice(0, activeTagIndex.value + 1),
4140
+ user,
4141
+ ...selectedUsers.value.slice(activeTagIndex.value + 1)
4142
+ ] : [...selectedUsers.value, user];
4143
+ updateSelectedUsers(updatedUsers);
4144
+ }
4145
+ if (activeTagIndex.value !== -1) {
4146
+ activeTagIndex.value = activeTagIndex.value + 1;
4147
+ }
4148
+ clearSearch();
4149
+ isFocused.value = true;
4150
+ nextTick(() => {
4151
+ var _a, _b, _c;
3871
4152
  if (activeTagIndex.value !== -1) {
3872
- const updatedUsers = [
3873
- ...props.selectedUsers.slice(0, activeTagIndex.value + 1),
3874
- user,
3875
- ...props.selectedUsers.slice(activeTagIndex.value + 1)
3876
- ];
3877
- emit("update:selectedUsers", updatedUsers);
4153
+ (_b = (_a = inlineInputRef.value) == null ? void 0 : _a[0]) == null ? void 0 : _b.focus();
3878
4154
  } else {
3879
- emit("update:selectedUsers", [...props.selectedUsers, user]);
4155
+ (_c = lastInputRef.value) == null ? void 0 : _c.focus();
3880
4156
  }
3881
- emit("add-user", user);
3882
- }
3883
- searchQuery.value = "";
3884
- showDropdown.value = false;
3885
- nextTick(() => {
3886
- var _a;
3887
- (_a = lastInputRef.value) == null ? void 0 : _a.focus();
3888
4157
  });
3889
- };
4158
+ }
3890
4159
  const removeUser = (user) => {
3891
4160
  if (!(user == null ? void 0 : user.id)) return;
3892
- const updatedUsers = props.selectedUsers.filter((item) => item.id !== user.id);
3893
- emit("update:selectedUsers", updatedUsers);
3894
- emit("remove-user", user);
4161
+ const updatedUsers = selectedUsers.value.filter((item) => item.id !== user.id);
4162
+ updateSelectedUsers(updatedUsers);
3895
4163
  if (activeTagIndex.value >= updatedUsers.length) {
3896
- activeTagIndex.value = updatedUsers.length - 1;
3897
- }
3898
- if (!isFocused.value) {
3899
- nextTick(() => {
3900
- calculateVisibleUsers();
3901
- });
4164
+ activeTagIndex.value = updatedUsers.length - 1;
3902
4165
  }
4166
+ scheduleVisibleUsersCalculation();
3903
4167
  };
3904
- const crossAxisOffset = ref(0);
3905
4168
  watch(
3906
- () => props.selectedUsers,
4169
+ selectedUsers,
3907
4170
  () => {
3908
- visibleUsers.value = [...props.selectedUsers];
3909
- if (!isFocused.value) {
3910
- nextTick(() => {
3911
- calculateVisibleUsers();
3912
- });
3913
- }
4171
+ scheduleVisibleUsersCalculation();
3914
4172
  },
3915
4173
  { deep: true }
3916
4174
  );
3917
4175
  watch(isFocused, (newVal) => {
3918
4176
  if (newVal) {
3919
- nextTick(() => {
3920
- initSortable();
3921
- });
4177
+ nextTick(() => initSortable());
3922
4178
  }
3923
4179
  });
3924
- const handleResize = () => {
3925
- if (!isFocused.value) {
3926
- calculateVisibleUsers();
4180
+ watch(
4181
+ () => props.userGroup,
4182
+ () => {
4183
+ initSelectedUsers();
3927
4184
  }
3928
- };
4185
+ );
4186
+ watch(
4187
+ () => props.modelValue,
4188
+ () => {
4189
+ const currentIds = selectedUsers.value.map((u) => u.id);
4190
+ const newIds = modelValueIds.value;
4191
+ if (currentIds.length !== newIds.length || !currentIds.every((id, index) => id === newIds[index])) {
4192
+ initSelectedUsers();
4193
+ }
4194
+ },
4195
+ { deep: true }
4196
+ );
4197
+ useResizeObserver(containerRef, () => {
4198
+ scheduleVisibleUsersCalculation();
4199
+ });
4200
+ onBeforeMount(() => {
4201
+ initSelectedUsers();
4202
+ });
3929
4203
  onMounted(() => {
3930
4204
  initSortable();
3931
- calculateVisibleUsers();
3932
- window.addEventListener("resize", handleResize);
3933
- nextTick(() => {
3934
- calculateVisibleUsers();
3935
- });
4205
+ nextTick(calculateVisibleUsers);
4206
+ });
4207
+ onUnmounted(() => {
4208
+ var _a;
4209
+ (_a = sortableInstance.value) == null ? void 0 : _a.destroy();
3936
4210
  });
3937
4211
  return (_ctx, _cache) => {
3938
4212
  return openBlock(), createElementBlock(
@@ -3940,34 +4214,32 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3940
4214
  {
3941
4215
  ref_key: "containerRef",
3942
4216
  ref: containerRef,
3943
- class: normalizeClass(["multiple-selector", { "is-disabled": _ctx.disabled }])
4217
+ class: normalizeClass(["bk-user-selector", { "is-disabled": _ctx.disabled }])
3944
4218
  },
3945
4219
  [
3946
4220
  createCommentVNode(" 下拉选项列表 "),
3947
4221
  createVNode(SelectionPopover, {
4222
+ "avatar-base-url": _ctx.avatarBaseUrl,
3948
4223
  "container-width": containerRef.value ? containerRef.value.offsetWidth : "auto",
3949
- "cross-axis-offset": crossAxisOffset.value,
3950
- "empty-text": _ctx.emptyText,
4224
+ "empty-text": computedEmptyText.value,
4225
+ "has-avatar": _ctx.hasAvatar,
3951
4226
  "is-show": showDropdown.value,
3952
4227
  loading: unref(searchLoading),
3953
- options: options.value,
4228
+ options: displayOptions.value,
3954
4229
  "render-list-item": _ctx.renderListItem,
3955
4230
  "search-query": unref(searchQuery),
3956
4231
  "tenant-id": _ctx.tenantId,
3957
- tenants: _ctx.tenants,
3958
- "user-group": userGroupFilter.value,
3959
- "user-group-name": _ctx.userGroupName,
4232
+ tenants: unref(tenants),
4233
+ "user-group": unref(filteredUserGroup),
4234
+ "user-group-name": computedUserGroupName.value,
3960
4235
  onClickOutside: handleClickOutside,
3961
4236
  onSelectUser: addUser
3962
4237
  }, {
3963
4238
  default: withCtx(() => [
3964
4239
  createCommentVNode(" 聚焦状态 - 可编辑模式 "),
3965
- isFocused.value ? (openBlock(), createElementBlock(
4240
+ withDirectives(createElementVNode(
3966
4241
  "div",
3967
4242
  {
3968
- key: 0,
3969
- ref_key: "tagsContainerRef",
3970
- ref: tagsContainerRef,
3971
4243
  class: "tags-container focused",
3972
4244
  onClick: withModifiers(handleContainerClick, ["stop"])
3973
4245
  },
@@ -3984,24 +4256,20 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3984
4256
  (openBlock(true), createElementBlock(
3985
4257
  Fragment,
3986
4258
  null,
3987
- renderList(_ctx.selectedUsers, (user, index) => {
4259
+ renderList(selectedUsers.value, (user, index) => {
3988
4260
  return openBlock(), createElementBlock("div", {
3989
4261
  key: user.id,
3990
- class: "tag-wrapper",
3991
- onClick: withModifiers(($event) => handleTagClick(index), ["stop"])
4262
+ class: "tag-wrapper"
3992
4263
  }, [
3993
- createVNode(UserTag, {
4264
+ createVNode(UserTag, mergeProps({ ref_for: true }, userTagCommonProps.value, {
3994
4265
  active: index === activeTagIndex.value,
3995
- "current-tenant-id": _ctx.tenantId,
3996
- draggable: _ctx.draggable,
3997
- "render-tag": _ctx.renderTag,
3998
- tenants: _ctx.tenants,
4266
+ draggable: _ctx.draggable && _ctx.multiple,
3999
4267
  user,
4000
4268
  onClick: ($event) => handleTagClick(index),
4001
4269
  onClose: ($event) => removeUser(user)
4002
- }, null, 8, ["active", "current-tenant-id", "draggable", "render-tag", "tenants", "user", "onClick", "onClose"]),
4270
+ }), null, 16, ["active", "draggable", "user", "onClick", "onClose"]),
4003
4271
  createCommentVNode(" 在当前激活标签后插入输入框 "),
4004
- index === activeTagIndex.value && activeTagIndex.value !== _ctx.selectedUsers.length - 1 ? withDirectives((openBlock(), createElementBlock(
4272
+ index === activeTagIndex.value && activeTagIndex.value !== selectedUsers.value.length - 1 ? withDirectives((openBlock(), createElementBlock(
4005
4273
  "input",
4006
4274
  {
4007
4275
  key: 0,
@@ -4009,42 +4277,45 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
4009
4277
  ref_key: "inlineInputRef",
4010
4278
  ref: inlineInputRef,
4011
4279
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(searchQuery) ? searchQuery.value = $event : null),
4012
- class: "search-input inline",
4280
+ autofocus: "",
4281
+ class: "search-input input-inline",
4282
+ style: normalizeStyle({ width: inputWidth.value }),
4013
4283
  onFocus: handleInputFocus,
4014
4284
  onInput: handleInput,
4015
4285
  onKeydown: handleKeyDown,
4016
- onPaste: handlePaste
4286
+ onPaste
4017
4287
  },
4018
4288
  null,
4019
- 544
4020
- /* NEED_HYDRATION, NEED_PATCH */
4289
+ 36
4290
+ /* STYLE, NEED_HYDRATION */
4021
4291
  )), [
4022
4292
  [vModelText, unref(searchQuery)]
4023
4293
  ]) : createCommentVNode("v-if", true)
4024
- ], 8, _hoisted_1$1);
4294
+ ]);
4025
4295
  }),
4026
4296
  128
4027
4297
  /* KEYED_FRAGMENT */
4028
4298
  )),
4029
4299
  createCommentVNode(" 最后一个输入框 "),
4030
- activeTagIndex.value === -1 || activeTagIndex.value === _ctx.selectedUsers.length - 1 ? withDirectives((openBlock(), createElementBlock("input", {
4300
+ activeTagIndex.value === -1 || activeTagIndex.value === selectedUsers.value.length - 1 ? withDirectives((openBlock(), createElementBlock("input", {
4031
4301
  key: 0,
4032
4302
  ref_key: "lastInputRef",
4033
4303
  ref: lastInputRef,
4034
4304
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => isRef(searchQuery) ? searchQuery.value = $event : null),
4035
- class: "search-input last",
4036
- placeholder: !_ctx.selectedUsers.length ? _ctx.placeholder : "",
4305
+ autofocus: "",
4306
+ class: "search-input input-last",
4307
+ placeholder: !selectedUsers.value.length ? computedPlaceholder.value : "",
4037
4308
  onFocus: handleInputFocus,
4038
4309
  onInput: handleInput,
4039
4310
  onKeydown: handleKeyDown,
4040
- onPaste: handlePaste
4041
- }, null, 40, _hoisted_2$1)), [
4311
+ onPaste
4312
+ }, null, 40, _hoisted_1)), [
4042
4313
  [vModelText, unref(searchQuery)]
4043
4314
  ]) : createCommentVNode("v-if", true),
4044
4315
  createCommentVNode(' "我"标签 '),
4045
4316
  createVNode(MeTag, {
4046
4317
  "current-user-id": _ctx.currentUserId,
4047
- "is-disabled": !!_ctx.currentUserId && _ctx.selectedUsers.some((user) => user.id === _ctx.currentUserId),
4318
+ "is-disabled": isMeTagDisabled.value,
4048
4319
  onClick: addCurrentUser
4049
4320
  }, null, 8, ["current-user-id", "is-disabled"])
4050
4321
  ],
@@ -4054,580 +4325,102 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
4054
4325
  ],
4055
4326
  512
4056
4327
  /* NEED_PATCH */
4057
- )) : (openBlock(), createElementBlock(
4058
- Fragment,
4059
- { key: 1 },
4328
+ ), [
4329
+ [vShow, isFocused.value]
4330
+ ]),
4331
+ createCommentVNode(" 未聚焦状态 - 只读展示模式 "),
4332
+ withDirectives(createElementVNode(
4333
+ "div",
4334
+ {
4335
+ ref_key: "collapsedContainerRef",
4336
+ ref: collapsedContainerRef,
4337
+ class: "tags-container tags-container-collapsed",
4338
+ onClick: withModifiers(handleFocus, ["stop"])
4339
+ },
4060
4340
  [
4061
- createCommentVNode(" 未聚焦状态 - 只读展示模式 "),
4062
- createElementVNode(
4063
- "div",
4064
- {
4065
- ref_key: "collapsedContainerRef",
4066
- ref: collapsedContainerRef,
4067
- class: "tags-container collapsed",
4068
- onClick: withModifiers(handleFocus, ["stop"])
4069
- },
4070
- [
4071
- (openBlock(true), createElementBlock(
4072
- Fragment,
4073
- null,
4074
- renderList(visibleUsers.value, (user) => {
4075
- return openBlock(), createBlock(UserTag, {
4076
- key: user.id,
4077
- "current-tenant-id": _ctx.tenantId,
4078
- "render-tag": _ctx.renderTag,
4079
- "show-tenant": true,
4080
- tenants: _ctx.tenants,
4081
- user,
4082
- onClick: handleFocus,
4083
- onClose: ($event) => removeUser(user)
4084
- }, null, 8, ["current-tenant-id", "render-tag", "tenants", "user", "onClose"]);
4085
- }),
4086
- 128
4087
- /* KEYED_FRAGMENT */
4088
- )),
4089
- createCommentVNode(" 显示折叠标签数量 "),
4090
- hiddenCount.value > 0 ? (openBlock(), createBlock(unref(Popover), {
4091
- key: 0,
4092
- placement: "top"
4093
- }, {
4094
- content: withCtx(() => [
4095
- createElementVNode("div", _hoisted_3, [
4096
- (openBlock(true), createElementBlock(
4097
- Fragment,
4098
- null,
4099
- renderList(_ctx.selectedUsers.slice(visibleUsers.value.length), (user) => {
4100
- return openBlock(), createBlock(unref(UserRender), {
4101
- key: user.id,
4102
- "tenant-id": _ctx.tenantId,
4103
- tenants: _ctx.tenants,
4104
- user
4105
- }, null, 8, ["tenant-id", "tenants", "user"]);
4106
- }),
4107
- 128
4108
- /* KEYED_FRAGMENT */
4109
- ))
4110
- ])
4111
- ]),
4341
+ (openBlock(true), createElementBlock(
4342
+ Fragment,
4343
+ null,
4344
+ renderList(visibleUsers.value, (user) => {
4345
+ return openBlock(), createBlock(UserTag, mergeProps({
4346
+ key: user.id,
4347
+ ref_for: true
4348
+ }, userTagCommonProps.value, {
4349
+ "show-tenant": true,
4350
+ user,
4351
+ onClick: handleFocus,
4352
+ onClose: ($event) => removeUser(user)
4353
+ }), null, 16, ["user", "onClose"]);
4354
+ }),
4355
+ 128
4356
+ /* KEYED_FRAGMENT */
4357
+ )),
4358
+ createCommentVNode(" 显示折叠标签数量 "),
4359
+ hiddenCount.value > 0 ? (openBlock(), createBlock(unref(Popover), {
4360
+ key: 0,
4361
+ placement: "top"
4362
+ }, {
4363
+ content: withCtx(() => [
4364
+ createElementVNode("div", _hoisted_2, [
4365
+ (openBlock(true), createElementBlock(
4366
+ Fragment,
4367
+ null,
4368
+ renderList(selectedUsers.value.slice(visibleUsers.value.length), (user) => {
4369
+ return openBlock(), createBlock(unref(UserRender), {
4370
+ key: user.id,
4371
+ "avatar-base-url": _ctx.avatarBaseUrl,
4372
+ "has-avatar": _ctx.hasAvatar,
4373
+ "tenant-id": _ctx.tenantId,
4374
+ tenants: unref(tenants),
4375
+ user
4376
+ }, null, 8, ["avatar-base-url", "has-avatar", "tenant-id", "tenants", "user"]);
4377
+ }),
4378
+ 128
4379
+ /* KEYED_FRAGMENT */
4380
+ ))
4381
+ ])
4382
+ ]),
4383
+ default: withCtx(() => [
4384
+ createVNode(unref(Tag), null, {
4112
4385
  default: withCtx(() => [
4113
- createVNode(unref(Tag), null, {
4114
- default: withCtx(() => [
4115
- createTextVNode(
4116
- " +" + toDisplayString(hiddenCount.value),
4117
- 1
4118
- /* TEXT */
4119
- )
4120
- ]),
4121
- _: 1
4122
- /* STABLE */
4123
- })
4386
+ createTextVNode(
4387
+ " +" + toDisplayString(hiddenCount.value),
4388
+ 1
4389
+ /* TEXT */
4390
+ )
4124
4391
  ]),
4125
4392
  _: 1
4126
4393
  /* STABLE */
4127
- })) : createCommentVNode("v-if", true),
4128
- createCommentVNode(" 搜索输入框 "),
4129
- withDirectives(createElementVNode("input", {
4130
- ref_key: "collapsedInputRef",
4131
- ref: collapsedInputRef,
4132
- "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isRef(searchQuery) ? searchQuery.value = $event : null),
4133
- class: "search-input collapsed",
4134
- placeholder: !_ctx.selectedUsers.length ? _ctx.placeholder : "",
4135
- onFocus: handleFocus
4136
- }, null, 40, _hoisted_4), [
4137
- [vModelText, unref(searchQuery)]
4138
- ]),
4139
- createCommentVNode(' 未聚焦状态下的"我"标签 '),
4140
- createVNode(MeTag, {
4141
- "current-user-id": _ctx.currentUserId,
4142
- "is-disabled": !!_ctx.currentUserId && _ctx.selectedUsers.some((user) => user[props.exactSearchKey] === _ctx.currentUserId),
4143
- onClick: addCurrentUser
4144
- }, null, 8, ["current-user-id", "is-disabled"])
4145
- ],
4146
- 512
4147
- /* NEED_PATCH */
4148
- )
4394
+ })
4395
+ ]),
4396
+ _: 1
4397
+ /* STABLE */
4398
+ })) : createCommentVNode("v-if", true),
4399
+ createCommentVNode(" 搜索输入框 "),
4400
+ withDirectives(createElementVNode("input", {
4401
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isRef(searchQuery) ? searchQuery.value = $event : null),
4402
+ class: "search-input search-input-collapsed",
4403
+ placeholder: !selectedUsers.value.length ? computedPlaceholder.value : "",
4404
+ onFocus: handleFocus
4405
+ }, null, 40, _hoisted_3), [
4406
+ [vModelText, unref(searchQuery)]
4407
+ ]),
4408
+ createCommentVNode(' 未聚焦状态下的""标签 '),
4409
+ createVNode(MeTag, {
4410
+ "current-user-id": _ctx.currentUserId,
4411
+ "is-disabled": isMeTagDisabled.value,
4412
+ onClick: addCurrentUser
4413
+ }, null, 8, ["current-user-id", "is-disabled"])
4149
4414
  ],
4150
- 2112
4151
- /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
4152
- ))
4153
- ]),
4154
- _: 1
4155
- /* STABLE */
4156
- }, 8, ["container-width", "cross-axis-offset", "empty-text", "is-show", "loading", "options", "render-list-item", "search-query", "tenant-id", "tenants", "user-group", "user-group-name"])
4157
- ],
4158
- 2
4159
- /* CLASS */
4160
- );
4161
- };
4162
- }
4163
- });
4164
- const MultipleSelector = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-2a532f24"]]);
4165
- const _hoisted_1 = { class: "input-container" };
4166
- const _hoisted_2 = ["placeholder"];
4167
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
4168
- ...{
4169
- name: "BkUserSelectorSingle"
4170
- },
4171
- __name: "single-selector",
4172
- props: {
4173
- modelValue: { default: "" },
4174
- tenants: {},
4175
- allowCreate: { type: Boolean },
4176
- apiBaseUrl: { default: "" },
4177
- currentUserId: { default: "" },
4178
- disabled: { type: Boolean },
4179
- emptyText: { default: "" },
4180
- enableMultiTenantMode: { type: Boolean },
4181
- exactSearchKey: { default: "bk_username" },
4182
- excludeUserIds: { default: () => [] },
4183
- freePaste: { type: Boolean },
4184
- placeholder: { default: "" },
4185
- tenantId: { default: "" },
4186
- userGroupName: { default: "" },
4187
- renderListItem: {},
4188
- renderTag: {},
4189
- userGroup: { default: () => [] }
4190
- },
4191
- emits: ["update:modelValue", "change", "focus", "blur"],
4192
- setup(__props, { emit: __emit }) {
4193
- const props = __props;
4194
- const emit = __emit;
4195
- const containerRef = ref(null);
4196
- const inputRef = ref(null);
4197
- const options = ref([]);
4198
- const isLoading = ref(false);
4199
- const selectedUser = ref(props.modelValue || "");
4200
- const searchQuery = ref("");
4201
- const showDropdown = ref(false);
4202
- const userGroupFilter = computed(() => {
4203
- return props.userGroup.filter((group) => {
4204
- var _a, _b;
4205
- const filtered = group.id !== selectedUser.value && !group.hidden;
4206
- if (filtered) {
4207
- return ((_a = group.id) == null ? void 0 : _a.includes(searchQuery.value)) || ((_b = group.name) == null ? void 0 : _b.includes(searchQuery.value));
4208
- }
4209
- return false;
4210
- });
4211
- });
4212
- const selectedUserInfo = computed(() => {
4213
- const userGroup = (props.userGroup || []).map((group) => ({
4214
- ...group,
4215
- tenantId: "",
4216
- type: "userGroup"
4217
- }));
4218
- const list = [...options.value, ...userGroup];
4219
- const selectedUserInfo2 = list.find((user) => user.id === selectedUser.value);
4220
- emit("change", selectedUserInfo2 || null);
4221
- return selectedUserInfo2;
4222
- });
4223
- const initSelectedUser = async () => {
4224
- if (typeof props.modelValue === "string" && props.modelValue) {
4225
- try {
4226
- isLoading.value = true;
4227
- const result = await lookupUsers({
4228
- apiBaseUrl: props.apiBaseUrl,
4229
- tenantId: props.tenantId,
4230
- exactSearchKey: props.exactSearchKey,
4231
- usersList: [props.modelValue],
4232
- enableMultiTenantMode: props.enableMultiTenantMode
4233
- });
4234
- options.value = formatUsers(result, props.enableMultiTenantMode).filter(
4235
- (user) => !props.excludeUserIds.includes(user.id)
4236
- );
4237
- if (props.userGroup.length > 0) {
4238
- const groupResult = props.userGroup.filter((group) => group.id == props.modelValue);
4239
- options.value = groupResult.map((group) => ({
4240
- ...group,
4241
- tenantId: "",
4242
- type: "userGroup"
4243
- }));
4244
- }
4245
- if (props.allowCreate && options.value.length === 0) {
4246
- options.value.push({
4247
- id: props.modelValue,
4248
- name: props.modelValue,
4249
- type: "custom",
4250
- tenantId: ""
4251
- });
4252
- }
4253
- } catch (error) {
4254
- console.error("获取用户信息失败:", error);
4255
- } finally {
4256
- isLoading.value = false;
4257
- }
4258
- } else {
4259
- options.value = [];
4260
- }
4261
- };
4262
- onBeforeMount(async () => {
4263
- initSelectedUser();
4264
- });
4265
- const addCurrentUser = async () => {
4266
- if (!props.currentUserId || selectedUser.value === props.currentUserId) return;
4267
- try {
4268
- const result = await lookupUsers({
4269
- apiBaseUrl: props.apiBaseUrl,
4270
- tenantId: props.tenantId,
4271
- exactSearchKey: props.exactSearchKey,
4272
- usersList: [props.currentUserId],
4273
- enableMultiTenantMode: props.enableMultiTenantMode
4274
- });
4275
- const formattedResults = formatUsers(result, props.enableMultiTenantMode);
4276
- if (formattedResults.length > 0) {
4277
- options.value = formattedResults.filter((user) => !props.excludeUserIds.includes(user.id));
4278
- addUser(formattedResults[0]);
4279
- }
4280
- } catch (error) {
4281
- console.error("获取当前用户信息失败:", error);
4282
- }
4283
- };
4284
- const fetchUsers = async (keyword = "") => {
4285
- if (!(keyword == null ? void 0 : keyword.length)) {
4286
- options.value = [];
4287
- isLoading.value = false;
4288
- return;
4289
- }
4290
- isLoading.value = true;
4291
- try {
4292
- const result = await searchUsers({
4293
- apiBaseUrl: props.apiBaseUrl,
4294
- tenantId: props.tenantId,
4295
- keyword,
4296
- enableMultiTenantMode: props.enableMultiTenantMode
4297
- });
4298
- options.value = formatUsers(result, props.enableMultiTenantMode).filter((user) => !selectedUser.value || user.id !== selectedUser.value).filter((user) => !props.excludeUserIds.includes(user.id));
4299
- } catch (error) {
4300
- console.error("获取用户列表失败:", error);
4301
- options.value = [];
4302
- } finally {
4303
- isLoading.value = false;
4304
- }
4305
- };
4306
- const handleKeyDown = (event) => {
4307
- if (event.key === "Enter") {
4308
- if (props.allowCreate) {
4309
- const customUser = {
4310
- id: searchQuery.value,
4311
- name: searchQuery.value,
4312
- tenantId: "",
4313
- type: "custom"
4314
- };
4315
- options.value.push(customUser);
4316
- addUser(customUser);
4317
- }
4318
- }
4319
- };
4320
- const handlePaste = (event) => {
4321
- var _a;
4322
- event.preventDefault();
4323
- const pastedText = ((_a = event.clipboardData) == null ? void 0 : _a.getData("text").trim()) || "";
4324
- if (props.freePaste) {
4325
- const customUser = { id: pastedText, name: pastedText, type: "custom", tenantId: "", login_name: pastedText };
4326
- if (!options.value.some((item) => item.login_name === customUser.login_name)) {
4327
- options.value.push(customUser);
4328
- }
4329
- addUser(customUser);
4330
- }
4331
- };
4332
- const addUser = (user) => {
4333
- selectedUser.value = user.id;
4334
- searchQuery.value = "";
4335
- showDropdown.value = false;
4336
- };
4337
- const removeSelectedUser = () => {
4338
- selectedUser.value = "";
4339
- searchQuery.value = "";
4340
- };
4341
- const handleInputFocus = () => {
4342
- if (searchQuery.value.length >= 1 || Array.isArray(props.userGroup) && props.userGroup.length > 0) {
4343
- showDropdown.value = true;
4344
- }
4345
- emit("focus");
4346
- };
4347
- let timer = null;
4348
- const handleInput = () => {
4349
- showDropdown.value = searchQuery.value.length >= 1;
4350
- isLoading.value = true;
4351
- clearTimeout(timer);
4352
- timer = setTimeout(() => {
4353
- fetchUsers(searchQuery.value);
4354
- }, 300);
4355
- };
4356
- const handleClickOutside = () => {
4357
- setTimeout(() => {
4358
- showDropdown.value = false;
4359
- }, 0);
4360
- };
4361
- watch(
4362
- () => props.modelValue,
4363
- (newVal) => {
4364
- selectedUser.value = newVal;
4365
- }
4366
- );
4367
- watch(selectedUser, (newVal) => {
4368
- emit("update:modelValue", newVal);
4369
- });
4370
- return (_ctx, _cache) => {
4371
- return withDirectives((openBlock(), createElementBlock(
4372
- "div",
4373
- {
4374
- ref_key: "containerRef",
4375
- ref: containerRef,
4376
- class: normalizeClass(["single-selector", { "is-disabled": _ctx.disabled }])
4377
- },
4378
- [
4379
- createCommentVNode(" 使用新的公共下拉选项组件 "),
4380
- createVNode(SelectionPopover, {
4381
- "container-width": containerRef.value ? containerRef.value.offsetWidth : "auto",
4382
- "empty-text": _ctx.emptyText,
4383
- "is-show": showDropdown.value,
4384
- loading: isLoading.value,
4385
- options: options.value,
4386
- "render-list-item": _ctx.renderListItem,
4387
- "search-query": searchQuery.value,
4388
- "tenant-id": _ctx.tenantId,
4389
- tenants: _ctx.tenants,
4390
- "user-group": userGroupFilter.value,
4391
- "user-group-name": _ctx.userGroupName,
4392
- onSelectUser: addUser
4393
- }, {
4394
- default: withCtx(() => [
4395
- createCommentVNode(" 输入框 "),
4396
- createElementVNode("div", _hoisted_1, [
4397
- createCommentVNode(" 用户标签显示 "),
4398
- selectedUserInfo.value ? (openBlock(), createElementBlock("div", {
4399
- key: 0,
4400
- onClick: withModifiers(removeSelectedUser, ["stop"])
4401
- }, [
4402
- createVNode(UserTag, {
4403
- "current-tenant-id": _ctx.tenantId,
4404
- "render-tag": _ctx.renderTag,
4405
- tenants: _ctx.tenants,
4406
- user: selectedUserInfo.value,
4407
- onClose: removeSelectedUser
4408
- }, null, 8, ["current-tenant-id", "render-tag", "tenants", "user"])
4409
- ])) : createCommentVNode("v-if", true),
4410
- withDirectives(createElementVNode("input", {
4411
- ref_key: "inputRef",
4412
- ref: inputRef,
4413
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
4414
- class: "search-input",
4415
- placeholder: selectedUserInfo.value ? "" : _ctx.placeholder,
4416
- onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur")),
4417
- onFocus: handleInputFocus,
4418
- onInput: handleInput,
4419
- onKeydown: handleKeyDown,
4420
- onPaste: handlePaste
4421
- }, null, 40, _hoisted_2), [
4422
- [vModelText, searchQuery.value]
4423
- ]),
4424
- createCommentVNode(' "我"标签 '),
4425
- createVNode(MeTag, {
4426
- "current-user-id": _ctx.currentUserId,
4427
- "is-disabled": !!_ctx.currentUserId && !!selectedUserInfo.value && selectedUserInfo.value[_ctx.exactSearchKey] === _ctx.currentUserId,
4428
- onClick: addCurrentUser
4429
- }, null, 8, ["current-user-id", "is-disabled"])
4415
+ 512
4416
+ /* NEED_PATCH */
4417
+ ), [
4418
+ [vShow, !isFocused.value]
4430
4419
  ])
4431
4420
  ]),
4432
4421
  _: 1
4433
4422
  /* STABLE */
4434
- }, 8, ["container-width", "empty-text", "is-show", "loading", "options", "render-list-item", "search-query", "tenant-id", "tenants", "user-group", "user-group-name"])
4435
- ],
4436
- 2
4437
- /* CLASS */
4438
- )), [
4439
- [unref(clickoutside), handleClickOutside]
4440
- ]);
4441
- };
4442
- }
4443
- });
4444
- const SingleSelector = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-cbe352a6"]]);
4445
- const _sfc_main = /* @__PURE__ */ defineComponent({
4446
- ...{
4447
- name: "BkUserSelector"
4448
- },
4449
- __name: "user-selector",
4450
- props: {
4451
- draggable: { type: Boolean, default: false },
4452
- modelValue: { default: "" },
4453
- multiple: { type: Boolean, default: false },
4454
- allowCreate: { type: Boolean, default: false },
4455
- apiBaseUrl: { default: "" },
4456
- currentUserId: { default: "" },
4457
- disabled: { type: Boolean, default: false },
4458
- emptyText: { default: "" },
4459
- enableMultiTenantMode: { type: Boolean, default: true },
4460
- exactSearchKey: { default: "bk_username" },
4461
- excludeUserIds: { default: () => [] },
4462
- freePaste: { type: Boolean, default: false },
4463
- placeholder: { default: "" },
4464
- tenantId: { default: "" },
4465
- userGroupName: { default: "" },
4466
- renderListItem: {},
4467
- renderTag: {},
4468
- userGroup: { default: () => [] }
4469
- },
4470
- emits: ["update:modelValue", "change", "dragStart", "dragEnd", "focus", "blur"],
4471
- setup(__props, { emit: __emit }) {
4472
- const { t } = useI18n();
4473
- provideGlobalConfig({
4474
- prefix: "bk"
4475
- });
4476
- const props = __props;
4477
- const emit = __emit;
4478
- const { tenants = {} } = useTenantData(props.apiBaseUrl, props.tenantId, props.enableMultiTenantMode);
4479
- const selectedUsers = ref([]);
4480
- const selectedUser = ref(props.multiple ? "" : props.modelValue);
4481
- const selectedUserIds = computed(() => {
4482
- return props.multiple ? selectedUsers.value.map((user) => user.id) : [];
4483
- });
4484
- const placeholder = computed(() => props.placeholder || t("请输入人员名称搜索"));
4485
- const userGroupName = computed(() => props.userGroupName || t("用户群组"));
4486
- const emptyText = computed(() => props.emptyText || t("无匹配人员"));
4487
- const initSelectedUsers = async () => {
4488
- if (props.multiple) {
4489
- const ids = Array.isArray(props.modelValue) ? props.modelValue : [];
4490
- let userGroupSelected = [];
4491
- if (props.userGroup.length > 0) {
4492
- const result = props.userGroup.filter((group) => ids.includes(group.id));
4493
- userGroupSelected = result.map((group) => ({
4494
- ...group,
4495
- tenantId: "",
4496
- type: "userGroup"
4497
- }));
4498
- }
4499
- if (ids.length > 0) {
4500
- try {
4501
- const result = await lookupUsers({
4502
- apiBaseUrl: props.apiBaseUrl,
4503
- tenantId: props.tenantId,
4504
- exactSearchKey: "bk_username",
4505
- usersList: ids,
4506
- enableMultiTenantMode: props.enableMultiTenantMode
4507
- });
4508
- const selectedList = [...userGroupSelected, ...formatUsers(result, props.enableMultiTenantMode)];
4509
- if (props.allowCreate) {
4510
- selectedList.push(
4511
- ...ids.filter((id) => !selectedList.some((user) => user.id === id)).map((id) => ({ id, name: id, type: "custom", tenantId: "" }))
4512
- );
4513
- }
4514
- selectedUsers.value = ids.map((id) => selectedList.find((user) => user.id === id)).filter(Boolean);
4515
- } catch (error) {
4516
- console.error("获取选中用户信息失败:", error);
4517
- }
4518
- } else {
4519
- selectedUsers.value = [];
4520
- }
4521
- } else {
4522
- selectedUser.value = props.modelValue;
4523
- }
4524
- };
4525
- const handleUpdateUser = (user) => {
4526
- emit("change", user);
4527
- };
4528
- const handleUpdateSelectedUsers = (users) => {
4529
- selectedUsers.value = users;
4530
- emit(
4531
- "update:modelValue",
4532
- users.map((user) => user.id)
4533
- );
4534
- emit("change", users);
4535
- };
4536
- const handleFocus = () => {
4537
- emit("focus");
4538
- };
4539
- const handleBlur = () => {
4540
- emit("blur");
4541
- };
4542
- watch(selectedUser, (newVal) => {
4543
- if (!props.multiple) {
4544
- emit("update:modelValue", newVal);
4545
- }
4546
- });
4547
- watch(
4548
- () => props.userGroup,
4549
- () => {
4550
- initSelectedUsers();
4551
- }
4552
- );
4553
- watch(
4554
- () => props.modelValue,
4555
- () => {
4556
- initSelectedUsers();
4557
- },
4558
- { deep: true }
4559
- );
4560
- onBeforeMount(() => {
4561
- initSelectedUsers();
4562
- });
4563
- return (_ctx, _cache) => {
4564
- return openBlock(), createElementBlock(
4565
- "section",
4566
- {
4567
- ref: "containerRef",
4568
- class: normalizeClass(["bk-user-selector", { "is-disabled": _ctx.disabled }])
4569
- },
4570
- [
4571
- createCommentVNode(" 单选模式 "),
4572
- !_ctx.multiple ? (openBlock(), createBlock(SingleSelector, {
4573
- key: 0,
4574
- modelValue: selectedUser.value,
4575
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedUser.value = $event),
4576
- "allow-create": _ctx.allowCreate,
4577
- "api-base-url": _ctx.apiBaseUrl,
4578
- "current-user-id": _ctx.currentUserId,
4579
- disabled: _ctx.disabled,
4580
- "empty-text": emptyText.value,
4581
- "enable-multi-tenant-mode": _ctx.enableMultiTenantMode,
4582
- "exact-search-key": _ctx.exactSearchKey,
4583
- "exclude-user-ids": _ctx.excludeUserIds,
4584
- placeholder: placeholder.value,
4585
- "render-list-item": _ctx.renderListItem,
4586
- "render-tag": _ctx.renderTag,
4587
- "tenant-id": _ctx.tenantId,
4588
- tenants: unref(tenants),
4589
- "user-group": _ctx.userGroup,
4590
- "user-group-name": userGroupName.value,
4591
- "free-paste": _ctx.freePaste,
4592
- onBlur: handleBlur,
4593
- onChange: handleUpdateUser,
4594
- onFocus: handleFocus
4595
- }, null, 8, ["modelValue", "allow-create", "api-base-url", "current-user-id", "disabled", "empty-text", "enable-multi-tenant-mode", "exact-search-key", "exclude-user-ids", "placeholder", "render-list-item", "render-tag", "tenant-id", "tenants", "user-group", "user-group-name", "free-paste"])) : (openBlock(), createElementBlock(
4596
- Fragment,
4597
- { key: 1 },
4598
- [
4599
- createCommentVNode(" 多选模式 "),
4600
- createVNode(MultipleSelector, {
4601
- modelValue: selectedUserIds.value,
4602
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => selectedUserIds.value = $event),
4603
- "allow-create": _ctx.allowCreate,
4604
- "api-base-url": _ctx.apiBaseUrl,
4605
- "current-user-id": _ctx.currentUserId,
4606
- disabled: _ctx.disabled,
4607
- draggable: _ctx.draggable,
4608
- "empty-text": emptyText.value,
4609
- "enable-multi-tenant-mode": _ctx.enableMultiTenantMode,
4610
- "exact-search-key": _ctx.exactSearchKey,
4611
- "exclude-user-ids": _ctx.excludeUserIds,
4612
- placeholder: placeholder.value,
4613
- "render-list-item": _ctx.renderListItem,
4614
- "render-tag": _ctx.renderTag,
4615
- "selected-users": selectedUsers.value,
4616
- "tenant-id": _ctx.tenantId,
4617
- tenants: unref(tenants),
4618
- "user-group": _ctx.userGroup,
4619
- "user-group-name": userGroupName.value,
4620
- "free-paste": _ctx.freePaste,
4621
- onBlur: handleBlur,
4622
- onDragEnd: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("dragEnd", $event)),
4623
- onDragStart: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("dragStart", $event)),
4624
- onFocus: handleFocus,
4625
- "onUpdate:selectedUsers": handleUpdateSelectedUsers
4626
- }, null, 8, ["modelValue", "allow-create", "api-base-url", "current-user-id", "disabled", "draggable", "empty-text", "enable-multi-tenant-mode", "exact-search-key", "exclude-user-ids", "placeholder", "render-list-item", "render-tag", "selected-users", "tenant-id", "tenants", "user-group", "user-group-name", "free-paste"])
4627
- ],
4628
- 2112
4629
- /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
4630
- ))
4423
+ }, 8, ["avatar-base-url", "container-width", "empty-text", "has-avatar", "is-show", "loading", "options", "render-list-item", "search-query", "tenant-id", "tenants", "user-group", "user-group-name"])
4631
4424
  ],
4632
4425
  2
4633
4426
  /* CLASS */
@@ -4635,7 +4428,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
4635
4428
  };
4636
4429
  }
4637
4430
  });
4638
- const BkUserSelector = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-9c628c83"]]);
4431
+ const BkUserSelector = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-9975c7e1"]]);
4639
4432
  export {
4640
4433
  BkUserSelector,
4641
4434
  BkUserSelector as default