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