UNPKG

@blueking/bk-user-display-name

Version:

多租户环境用于显示用户名称的组件

207 lines (206 loc) 7.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.USER_ID_FIELD = exports.CUSTOM_ELEMENT_NAME = void 0; exports.CUSTOM_ELEMENT_NAME = 'bk-user-display-name'; exports.USER_ID_FIELD = 'user-id'; /** * 蓝鲸用户显示名称自定义元素类 * 用于在页面中显示用户的友好显示名称,支持缓存和批量查询 * @class BkUserDisplayName * @extends HTMLElement */ class BkUserDisplayName extends HTMLElement { constructor() { super(); } /** * 配置类的静态参数 * @static * @param {ConfigOptions} config - 配置选项 * @returns {void} */ static configure(config) { if (config.apiBaseUrl) { this.apiBaseUrl = config.apiBaseUrl; } if (config.tenantId) { this.tenantId = config.tenantId; } if (typeof config.cacheDuration === 'number') { this.cacheDuration = config.cacheDuration; } if (config.emptyText !== undefined) { this.emptyText = config.emptyText; } } /** * 通用请求配置 * @private * @returns {RequestInit} 通用请求配置 */ createFetchConfig() { return { credentials: 'include', headers: { 'X-Bk-Tenant-Id': BkUserDisplayName.tenantId, }, }; } /** * 获取单个用户信息 * 支持请求去重,避免同时发起多个相同的请求 * @async * @param {string} id - 用户ID * @returns {Promise<UserResponse>} 用户信息 */ async fetchUser(id) { const pendingRequest = BkUserDisplayName.pendingRequests.get(id); if (pendingRequest) { return pendingRequest; } const promise = fetch(`${BkUserDisplayName.apiBaseUrl}/api/v3/open-web/tenant/users/${id}/display_info/`, this.createFetchConfig()) .then(response => response.json()) .finally(() => { BkUserDisplayName.pendingRequests.delete(id); }); BkUserDisplayName.pendingRequests.set(id, promise); return promise; } /** * 批量获取多个用户信息 * @async * @param {string[]} ids - 用户ID数组 * @returns {Promise<UsersResponse>} 用户信息列表 */ async fetchUsers(ids) { return fetch(`${BkUserDisplayName.apiBaseUrl}/api/v3/open-web/tenant/users/-/display_info/?bk_usernames=${ids.join(',')}`, this.createFetchConfig()).then(response => response.json()); } /** * 检查缓存是否仍然有效 * @private * @param {UserCacheItem} cached - 缓存项 * @returns {boolean} 缓存是否有效 */ isCacheValid(cached) { return Date.now() - cached.timestamp < BkUserDisplayName.cacheDuration; } /** * 解析用户ID字符串为ID数组 * 支持逗号、中文逗号、分号分隔 * @private * @param {string} userIdString - 用户ID字符串 * @returns {string[]} 解析后的用户ID数组 */ parseUserIds(userIdString) { return decodeURIComponent(userIdString).split(/[,,;]/).filter(id => id.trim()).map(id => id.trim()); } /** * 获取单个用户的显示名称 * 优先使用缓存,缓存失效时重新请求 * @private * @async * @param {string} id - 用户ID * @returns {Promise<string>} 用户显示名称 */ async getSingleUserDisplayName(id) { var _a; const cached = BkUserDisplayName.userCache.get(id); let userResponse; if (cached && this.isCacheValid(cached)) { userResponse = cached.data; } else { userResponse = await this.fetchUser(id); BkUserDisplayName.userCache.set(id, { data: userResponse, timestamp: Date.now(), }); } return ((_a = userResponse.data) === null || _a === void 0 ? void 0 : _a.display_name) || id; } /** * 获取多个用户的显示名称 * @private * @async * @param {string[]} ids - 用户ID数组 * @returns {Promise<string>} 逗号分隔的用户显示名称字符串 */ async getMultipleUsersDisplayName(ids) { const usersResponse = await this.fetchUsers(ids); const userList = ids.map(id => { var _a; const user = (_a = usersResponse.data) === null || _a === void 0 ? void 0 : _a.find((user) => user.bk_username === id); return (user === null || user === void 0 ? void 0 : user.display_name) || id; }); return userList.join(', '); } /** * 获取用户显示名称 * 根据用户ID的数量选择单个或批量获取方式 * @async * @returns {Promise<string>} 用户显示名称或用户ID(获取失败时) */ async getDisplayName() { var _a; const id = (_a = this.getAttribute(exports.USER_ID_FIELD)) === null || _a === void 0 ? void 0 : _a.trim(); if (!id) return ''; // 如果未配置,则直接展示用户配置 这里用于 当前项目回退到原来的展示方式 if (!BkUserDisplayName.apiBaseUrl || !BkUserDisplayName.tenantId) return id; const ids = this.parseUserIds(id); try { if (ids.length === 1) { return await this.getSingleUserDisplayName(id); } else { return await this.getMultipleUsersDisplayName(ids); } } catch (error) { console.error('DisplayName 获取用户数据失败:', error); return id; } } /** * 更新元素显示内容 * @async * @returns {Promise<void>} */ async updateDisplay() { const id = this.getAttribute(exports.USER_ID_FIELD); if (!id) { this.textContent = BkUserDisplayName.emptyText; return; } this.textContent = '...'; this.textContent = await this.getDisplayName(); } /** * 当user-id属性发生变化时触发显示更新 */ attributeChangedCallback(name, oldValue, newValue) { if (name === exports.USER_ID_FIELD && oldValue !== newValue) { this.updateDisplay(); } } } exports.default = BkUserDisplayName; /** 用户数据缓存 */ BkUserDisplayName.userCache = new Map(); /** 缓存过期时间(毫秒),默认5分钟 */ BkUserDisplayName.cacheDuration = 5 * 60 * 1000; /** 存储进行中的请求,避免重复请求 */ BkUserDisplayName.pendingRequests = new Map(); /** API基础URL */ BkUserDisplayName.apiBaseUrl = ''; /** 租户ID */ BkUserDisplayName.tenantId = ''; /** 当输入为空时显示的文本 */ BkUserDisplayName.emptyText = '--'; /** 定义需要监听的属性列表 */ BkUserDisplayName.observedAttributes = [exports.USER_ID_FIELD]; // 微前端框架下,有多个应用重复注册 if (!customElements.get(exports.CUSTOM_ELEMENT_NAME)) { customElements.define(exports.CUSTOM_ELEMENT_NAME, BkUserDisplayName); }