From 6244e8b5c00065d92a1e91d2d70ea6d3f8febd40 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Fri, 24 Feb 2023 14:06:14 +0800 Subject: [PATCH] refactor: request api of user data (#882) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement #### What this PR does / why we need it: 重构获取用户信息的请求方式,无需再请求所有角色即可获取当前用户的角色信息,适配:https://github.com/halo-dev/halo/pull/3372 相关 PR:https://github.com/halo-dev/console/pull/847 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/3342 #### Special notes for your reviewer: 测试方式: 1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/3372 分支。 2. Console 需要 `pnpm install && pnpm build:packages` 3. 测试用户列表、登录、检查角色信息是否显示正确。 #### Does this PR introduce a user-facing change? ```release-note 优化 Console 端用户角色标识的显示名称。 ``` --- .../api-client/src/.openapi-generator/FILES | 3 + .../api-console-halo-run-v1alpha1-user-api.ts | 146 +++++++++++++++--- .../api-client/src/models/detailed-user.ts | 40 +++++ packages/api-client/src/models/index.ts | 3 + .../api-client/src/models/listed-user-list.ts | 79 ++++++++++ packages/api-client/src/models/listed-user.ts | 40 +++++ src/layouts/BasicLayout.vue | 35 ++--- src/main.ts | 3 - src/modules/system/roles/RoleList.vue | 4 - src/modules/system/users/UserDetail.vue | 45 +++--- src/modules/system/users/UserList.vue | 60 ++++--- .../users/layouts/UserProfileLayout.vue | 26 ++-- src/stores/role.ts | 29 +--- src/stores/user.ts | 9 +- 14 files changed, 370 insertions(+), 152 deletions(-) create mode 100644 packages/api-client/src/models/detailed-user.ts create mode 100644 packages/api-client/src/models/listed-user-list.ts create mode 100644 packages/api-client/src/models/listed-user.ts diff --git a/packages/api-client/src/.openapi-generator/FILES b/packages/api-client/src/.openapi-generator/FILES index 42596253..76d617bb 100644 --- a/packages/api-client/src/.openapi-generator/FILES +++ b/packages/api-client/src/.openapi-generator/FILES @@ -77,6 +77,7 @@ models/counter-request.ts models/counter.ts models/custom-templates.ts models/dashboard-stats.ts +models/detailed-user.ts models/excerpt.ts models/extension.ts models/file-reverse-proxy-provider.ts @@ -96,6 +97,8 @@ models/listed-reply-list.ts models/listed-reply.ts models/listed-single-page-list.ts models/listed-single-page.ts +models/listed-user-list.ts +models/listed-user.ts models/login-history.ts models/menu-item-list.ts models/menu-item-spec.ts diff --git a/packages/api-client/src/api/api-console-halo-run-v1alpha1-user-api.ts b/packages/api-client/src/api/api-console-halo-run-v1alpha1-user-api.ts index 1e90edf0..f4354aa3 100644 --- a/packages/api-client/src/api/api-console-halo-run-v1alpha1-user-api.ts +++ b/packages/api-client/src/api/api-console-halo-run-v1alpha1-user-api.ts @@ -34,11 +34,13 @@ import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } fr // @ts-ignore import { ChangePasswordRequest } from '../models' // @ts-ignore +import { DetailedUser } from '../models' +// @ts-ignore import { GrantRequest } from '../models' // @ts-ignore -import { User } from '../models' +import { ListedUserList } from '../models' // @ts-ignore -import { UserList } from '../models' +import { User } from '../models' // @ts-ignore import { UserPermission } from '../models' /** @@ -174,6 +176,47 @@ export const ApiConsoleHaloRunV1alpha1UserApiAxiosParamCreator = function (confi options: localVarRequestOptions, } }, + /** + * Get user detail by name + * @param {string} name User name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserDetail: async (name: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'name' is not null or undefined + assertParamExists('getUserDetail', 'name', name) + const localVarPath = `/apis/api.console.halo.run/v1alpha1/users/{name}`.replace( + `{${'name'}}`, + encodeURIComponent(String(name)), + ) + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL) + let baseOptions + if (configuration) { + baseOptions = configuration.baseOptions + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options } + const localVarHeaderParameter = {} as any + const localVarQueryParameter = {} as any + + // authentication BasicAuth required + // http basic authentication required + setBasicAuthToObject(localVarRequestOptions, configuration) + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + setSearchParams(localVarUrlObj, localVarQueryParameter) + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {} + localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers } + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + } + }, /** * Grant permissions to user * @param {string} name User name @@ -231,9 +274,9 @@ export const ApiConsoleHaloRunV1alpha1UserApiAxiosParamCreator = function (confi * @param {string} [keyword] * @param {string} [role] * @param {number} [size] Size of one page. Zero indicates no limit. - * @param {number} [page] The page number. Zero indicates no page. * @param {Array} [labelSelector] Label selector for filtering. * @param {Array} [fieldSelector] Field selector for filtering. + * @param {number} [page] The page number. Zero indicates no page. * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -242,9 +285,9 @@ export const ApiConsoleHaloRunV1alpha1UserApiAxiosParamCreator = function (confi keyword?: string, role?: string, size?: number, - page?: number, labelSelector?: Array, fieldSelector?: Array, + page?: number, options: AxiosRequestConfig = {}, ): Promise => { const localVarPath = `/apis/api.console.halo.run/v1alpha1/users` @@ -283,10 +326,6 @@ export const ApiConsoleHaloRunV1alpha1UserApiAxiosParamCreator = function (confi localVarQueryParameter['size'] = size } - if (page !== undefined) { - localVarQueryParameter['page'] = page - } - if (labelSelector) { localVarQueryParameter['labelSelector'] = labelSelector } @@ -295,6 +334,10 @@ export const ApiConsoleHaloRunV1alpha1UserApiAxiosParamCreator = function (confi localVarQueryParameter['fieldSelector'] = fieldSelector } + if (page !== undefined) { + localVarQueryParameter['page'] = page + } + setSearchParams(localVarUrlObj, localVarQueryParameter) let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {} localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers } @@ -377,7 +420,7 @@ export const ApiConsoleHaloRunV1alpha1UserApiFp = function (configuration?: Conf */ async getCurrentUserDetail( options?: AxiosRequestConfig, - ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.getCurrentUserDetail(options) return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration) }, @@ -394,6 +437,19 @@ export const ApiConsoleHaloRunV1alpha1UserApiFp = function (configuration?: Conf const localVarAxiosArgs = await localVarAxiosParamCreator.getPermissions(name, options) return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration) }, + /** + * Get user detail by name + * @param {string} name User name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserDetail( + name: string, + options?: AxiosRequestConfig, + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserDetail(name, options) + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration) + }, /** * Grant permissions to user * @param {string} name User name @@ -415,9 +471,9 @@ export const ApiConsoleHaloRunV1alpha1UserApiFp = function (configuration?: Conf * @param {string} [keyword] * @param {string} [role] * @param {number} [size] Size of one page. Zero indicates no limit. - * @param {number} [page] The page number. Zero indicates no page. * @param {Array} [labelSelector] Label selector for filtering. * @param {Array} [fieldSelector] Field selector for filtering. + * @param {number} [page] The page number. Zero indicates no page. * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -426,19 +482,19 @@ export const ApiConsoleHaloRunV1alpha1UserApiFp = function (configuration?: Conf keyword?: string, role?: string, size?: number, - page?: number, labelSelector?: Array, fieldSelector?: Array, + page?: number, options?: AxiosRequestConfig, - ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.listUsers( sort, keyword, role, size, - page, labelSelector, fieldSelector, + page, options, ) return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration) @@ -489,7 +545,7 @@ export const ApiConsoleHaloRunV1alpha1UserApiFactory = function ( * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getCurrentUserDetail(options?: AxiosRequestConfig): AxiosPromise { + getCurrentUserDetail(options?: AxiosRequestConfig): AxiosPromise { return localVarFp.getCurrentUserDetail(options).then((request) => request(axios, basePath)) }, /** @@ -504,6 +560,18 @@ export const ApiConsoleHaloRunV1alpha1UserApiFactory = function ( ): AxiosPromise { return localVarFp.getPermissions(requestParameters.name, options).then((request) => request(axios, basePath)) }, + /** + * Get user detail by name + * @param {ApiConsoleHaloRunV1alpha1UserApiGetUserDetailRequest} requestParameters Request parameters. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserDetail( + requestParameters: ApiConsoleHaloRunV1alpha1UserApiGetUserDetailRequest, + options?: AxiosRequestConfig, + ): AxiosPromise { + return localVarFp.getUserDetail(requestParameters.name, options).then((request) => request(axios, basePath)) + }, /** * Grant permissions to user * @param {ApiConsoleHaloRunV1alpha1UserApiGrantPermissionRequest} requestParameters Request parameters. @@ -527,16 +595,16 @@ export const ApiConsoleHaloRunV1alpha1UserApiFactory = function ( listUsers( requestParameters: ApiConsoleHaloRunV1alpha1UserApiListUsersRequest = {}, options?: AxiosRequestConfig, - ): AxiosPromise { + ): AxiosPromise { return localVarFp .listUsers( requestParameters.sort, requestParameters.keyword, requestParameters.role, requestParameters.size, - requestParameters.page, requestParameters.labelSelector, requestParameters.fieldSelector, + requestParameters.page, options, ) .then((request) => request(axios, basePath)) @@ -591,6 +659,20 @@ export interface ApiConsoleHaloRunV1alpha1UserApiGetPermissionsRequest { readonly name: string } +/** + * Request parameters for getUserDetail operation in ApiConsoleHaloRunV1alpha1UserApi. + * @export + * @interface ApiConsoleHaloRunV1alpha1UserApiGetUserDetailRequest + */ +export interface ApiConsoleHaloRunV1alpha1UserApiGetUserDetailRequest { + /** + * User name + * @type {string} + * @memberof ApiConsoleHaloRunV1alpha1UserApiGetUserDetail + */ + readonly name: string +} + /** * Request parameters for grantPermission operation in ApiConsoleHaloRunV1alpha1UserApi. * @export @@ -646,13 +728,6 @@ export interface ApiConsoleHaloRunV1alpha1UserApiListUsersRequest { */ readonly size?: number - /** - * The page number. Zero indicates no page. - * @type {number} - * @memberof ApiConsoleHaloRunV1alpha1UserApiListUsers - */ - readonly page?: number - /** * Label selector for filtering. * @type {Array} @@ -666,6 +741,13 @@ export interface ApiConsoleHaloRunV1alpha1UserApiListUsersRequest { * @memberof ApiConsoleHaloRunV1alpha1UserApiListUsers */ readonly fieldSelector?: Array + + /** + * The page number. Zero indicates no page. + * @type {number} + * @memberof ApiConsoleHaloRunV1alpha1UserApiListUsers + */ + readonly page?: number } /** @@ -733,6 +815,22 @@ export class ApiConsoleHaloRunV1alpha1UserApi extends BaseAPI { .then((request) => request(this.axios, this.basePath)) } + /** + * Get user detail by name + * @param {ApiConsoleHaloRunV1alpha1UserApiGetUserDetailRequest} requestParameters Request parameters. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ApiConsoleHaloRunV1alpha1UserApi + */ + public getUserDetail( + requestParameters: ApiConsoleHaloRunV1alpha1UserApiGetUserDetailRequest, + options?: AxiosRequestConfig, + ) { + return ApiConsoleHaloRunV1alpha1UserApiFp(this.configuration) + .getUserDetail(requestParameters.name, options) + .then((request) => request(this.axios, this.basePath)) + } + /** * Grant permissions to user * @param {ApiConsoleHaloRunV1alpha1UserApiGrantPermissionRequest} requestParameters Request parameters. @@ -766,9 +864,9 @@ export class ApiConsoleHaloRunV1alpha1UserApi extends BaseAPI { requestParameters.keyword, requestParameters.role, requestParameters.size, - requestParameters.page, requestParameters.labelSelector, requestParameters.fieldSelector, + requestParameters.page, options, ) .then((request) => request(this.axios, this.basePath)) diff --git a/packages/api-client/src/models/detailed-user.ts b/packages/api-client/src/models/detailed-user.ts new file mode 100644 index 00000000..44ec77c9 --- /dev/null +++ b/packages/api-client/src/models/detailed-user.ts @@ -0,0 +1,40 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Halo Next API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +// May contain unused imports in some cases +// @ts-ignore +import { Role } from './role' +// May contain unused imports in some cases +// @ts-ignore +import { User } from './user' + +/** + * + * @export + * @interface DetailedUser + */ +export interface DetailedUser { + /** + * + * @type {User} + * @memberof DetailedUser + */ + user: User + /** + * + * @type {Array} + * @memberof DetailedUser + */ + roles: Array +} diff --git a/packages/api-client/src/models/index.ts b/packages/api-client/src/models/index.ts index 771138e9..c032ac68 100644 --- a/packages/api-client/src/models/index.ts +++ b/packages/api-client/src/models/index.ts @@ -31,6 +31,7 @@ export * from './counter-list' export * from './counter-request' export * from './custom-templates' export * from './dashboard-stats' +export * from './detailed-user' export * from './excerpt' export * from './extension' export * from './file-reverse-proxy-provider' @@ -49,6 +50,8 @@ export * from './listed-reply' export * from './listed-reply-list' export * from './listed-single-page' export * from './listed-single-page-list' +export * from './listed-user' +export * from './listed-user-list' export * from './login-history' export * from './menu' export * from './menu-item' diff --git a/packages/api-client/src/models/listed-user-list.ts b/packages/api-client/src/models/listed-user-list.ts new file mode 100644 index 00000000..26427343 --- /dev/null +++ b/packages/api-client/src/models/listed-user-list.ts @@ -0,0 +1,79 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Halo Next API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +// May contain unused imports in some cases +// @ts-ignore +import { ListedUser } from './listed-user' + +/** + * + * @export + * @interface ListedUserList + */ +export interface ListedUserList { + /** + * Page number, starts from 1. If not set or equal to 0, it means no pagination. + * @type {number} + * @memberof ListedUserList + */ + page: number + /** + * Size of each page. If not set or equal to 0, it means no pagination. + * @type {number} + * @memberof ListedUserList + */ + size: number + /** + * Total elements. + * @type {number} + * @memberof ListedUserList + */ + total: number + /** + * A chunk of items. + * @type {Array} + * @memberof ListedUserList + */ + items: Array + /** + * Indicates whether current page is the first page. + * @type {boolean} + * @memberof ListedUserList + */ + first: boolean + /** + * Indicates whether current page is the last page. + * @type {boolean} + * @memberof ListedUserList + */ + last: boolean + /** + * Indicates whether current page has previous page. + * @type {boolean} + * @memberof ListedUserList + */ + hasNext: boolean + /** + * Indicates whether current page has previous page. + * @type {boolean} + * @memberof ListedUserList + */ + hasPrevious: boolean + /** + * Indicates total pages. + * @type {number} + * @memberof ListedUserList + */ + totalPages: number +} diff --git a/packages/api-client/src/models/listed-user.ts b/packages/api-client/src/models/listed-user.ts new file mode 100644 index 00000000..706048b6 --- /dev/null +++ b/packages/api-client/src/models/listed-user.ts @@ -0,0 +1,40 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Halo Next API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +// May contain unused imports in some cases +// @ts-ignore +import { Role } from './role' +// May contain unused imports in some cases +// @ts-ignore +import { User } from './user' + +/** + * A chunk of items. + * @export + * @interface ListedUser + */ +export interface ListedUser { + /** + * + * @type {User} + * @memberof ListedUser + */ + user: User + /** + * + * @type {Array} + * @memberof ListedUser + */ + roles: Array +} diff --git a/src/layouts/BasicLayout.vue b/src/layouts/BasicLayout.vue index ff0f4031..ea6721f6 100644 --- a/src/layouts/BasicLayout.vue +++ b/src/layouts/BasicLayout.vue @@ -18,7 +18,7 @@ import { useRouter, type RouteRecordRaw, } from "vue-router"; -import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue"; +import { nextTick, onMounted, onUnmounted, ref, watch } from "vue"; import axios from "axios"; import GlobalSearchModal from "@/components/global-search/GlobalSearchModal.vue"; import LoginModal from "@/components/login/LoginModal.vue"; @@ -29,7 +29,7 @@ import { hasPermission } from "@/utils/permission"; import { useUserStore } from "@/stores/user"; import { rbacAnnotations } from "@/constants/annotations"; import { useScroll } from "@vueuse/core"; -import { defineStore } from "pinia"; +import { defineStore, storeToRefs } from "pinia"; const route = useRoute(); const router = useRouter(); @@ -39,6 +39,8 @@ const moreMenuRootVisible = ref(false); const userStore = useUserStore(); +const { currentRoles, currentUser } = storeToRefs(userStore); + const handleLogout = () => { Dialog.warning({ title: "确定要退出登录吗?", @@ -58,19 +60,6 @@ const handleLogout = () => { }); }; -const currentRole = computed(() => { - const names = JSON.parse( - userStore.currentUser?.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] || - "[]" - ); - - if (names.length === 0) { - return; - } - - return roleStore.getRoleDisplayName(names[0]); -}); - // Global Search const globalSearchVisible = ref(false); @@ -249,24 +238,28 @@ onMounted(() => {
-
+
- {{ userStore.currentUser?.spec.displayName }} + {{ currentUser?.spec.displayName }}
-
+
- {{ currentRole }} + {{ + currentRoles[0].metadata.annotations?.[ + rbacAnnotations.DISPLAY_NAME + ] || currentRoles[0].metadata.name + }}
diff --git a/src/main.ts b/src/main.ts index 061e9460..03f0100a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -244,9 +244,6 @@ async function initApp() { await loadUserPermissions(); - const roleStore = useRoleStore(); - await roleStore.fetchRoles(); - try { await loadPluginModules(); } catch (e) { diff --git a/src/modules/system/roles/RoleList.vue b/src/modules/system/roles/RoleList.vue index 303de9b0..e1eca6f7 100644 --- a/src/modules/system/roles/RoleList.vue +++ b/src/modules/system/roles/RoleList.vue @@ -36,9 +36,7 @@ import Fuse from "fuse.js"; import { usePermission } from "@/utils/permission"; import { roleLabels } from "@/constants/labels"; import { SUPER_ROLE_NAME } from "@/constants/constants"; -import { useRoleStore } from "@/stores/role"; -const roleStore = useRoleStore(); const { currentUserHasPermission } = usePermission(); const editingModal = ref(false); @@ -93,7 +91,6 @@ const handleOpenEditingModal = (role: Role) => { const onEditingModalClose = () => { selectedRole.value = undefined; handleFetchRoles(); - roleStore.fetchRoles(); }; const handleCloneRole = async (role: Role) => { @@ -143,7 +140,6 @@ const handleDelete = async (role: Role) => { console.error("Failed to delete role", e); } finally { handleFetchRoles(); - roleStore.fetchRoles(); } }, }); diff --git a/src/modules/system/users/UserDetail.vue b/src/modules/system/users/UserDetail.vue index fd710a1a..d8181a06 100644 --- a/src/modules/system/users/UserDetail.vue +++ b/src/modules/system/users/UserDetail.vue @@ -1,26 +1,13 @@ @@ -32,7 +19,7 @@ const router = useRouter(); >
显示名称
- {{ user?.spec?.displayName }} + {{ user?.user.spec?.displayName }}
用户名
- {{ user?.metadata?.name }} + {{ user?.user.metadata?.name }}
电子邮箱
- {{ user?.spec?.email || "未设置" }} + {{ user?.user.spec?.email || "未设置" }}
角色
- {{ role }} + {{ + role.metadata.annotations?.[rbacAnnotations.DISPLAY_NAME] || + role.metadata.name + }}
@@ -73,7 +68,7 @@ const router = useRouter(); >
描述
- {{ user?.spec?.bio || "无" }} + {{ user?.user.spec?.bio || "无" }}
- {{ formatDatetime(user?.metadata?.creationTimestamp) }} + {{ formatDatetime(user?.user.metadata?.creationTimestamp) }}
@@ -93,7 +88,7 @@ const router = useRouter(); >
最近登录时间
- {{ user?.metadata?.creationTimestamp }} + {{ user?.user.metadata?.creationTimestamp }}
diff --git a/src/modules/system/users/UserList.vue b/src/modules/system/users/UserList.vue index d095a7da..1b9a0b23 100644 --- a/src/modules/system/users/UserList.vue +++ b/src/modules/system/users/UserList.vue @@ -25,13 +25,12 @@ import UserPasswordChangeModal from "./components/UserPasswordChangeModal.vue"; import GrantPermissionModal from "./components/GrantPermissionModal.vue"; import { computed, onMounted, onUnmounted, ref, watch } from "vue"; import { apiClient } from "@/utils/api-client"; -import type { Role, User, UserList } from "@halo-dev/api-client"; +import type { Role, User, ListedUserList } from "@halo-dev/api-client"; import { rbacAnnotations } from "@/constants/annotations"; import { formatDatetime } from "@/utils/date"; import { useRouteQuery } from "@vueuse/router"; import { usePermission } from "@/utils/permission"; import { useUserStore } from "@/stores/user"; -import { useRoleStore } from "@/stores/role"; import { getNode } from "@formkit/core"; import FilterTag from "@/components/filter/FilterTag.vue"; import { useFetchRole } from "../roles/composables/use-role"; @@ -44,7 +43,7 @@ const editingModal = ref(false); const passwordChangeModal = ref(false); const grantPermissionModal = ref(false); -const users = ref({ +const users = ref({ page: 1, size: 20, total: 0, @@ -62,7 +61,6 @@ const keyword = ref(""); const refreshInterval = ref(); const userStore = useUserStore(); -const roleStore = useRoleStore(); const ANONYMOUSUSER_NAME = "anonymousUser"; const DELETEDUSER_NAME = "ghost"; @@ -99,7 +97,7 @@ const handleFetchUsers = async (options?: { users.value = data; const deletedUsers = users.value.items.filter( - (user) => !!user.metadata.deletionTimestamp + (user) => !!user.user.metadata.deletionTimestamp ); if (deletedUsers.length) { @@ -188,7 +186,7 @@ const handleCheckAllChange = (e: Event) => { if (checked) { selectedUserNames.value = users.value.items.map((user) => { - return user.metadata.name; + return user.user.metadata.name; }) || []; } else { selectedUserNames.value.length = 0; @@ -215,16 +213,6 @@ const handleOpenGrantPermissionModal = (user: User) => { grantPermissionModal.value = true; }; -const getRoles = (user: User) => { - const names = JSON.parse( - user.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]" - ); - - return names.map((name: string) => { - return roleStore.getRoleDisplayName(name); - }); -}; - onMounted(() => { handleFetchUsers(); }); @@ -521,14 +509,14 @@ const hasFilters = computed(() => { role="list" >
  • - + @@ -557,17 +545,21 @@ const hasFilters = computed(() => { - + @@ -575,7 +567,7 @@ const hasFilters = computed(() => { @@ -588,35 +580,37 @@ const hasFilters = computed(() => { v-close-popper block type="secondary" - @click="handleOpenCreateModal(user)" + @click="handleOpenCreateModal(user.user)" > 修改资料 修改密码 分配角色 删除 diff --git a/src/modules/system/users/layouts/UserProfileLayout.vue b/src/modules/system/users/layouts/UserProfileLayout.vue index 17a8c5d6..7a598c7a 100644 --- a/src/modules/system/users/layouts/UserProfileLayout.vue +++ b/src/modules/system/users/layouts/UserProfileLayout.vue @@ -2,9 +2,9 @@ import BasicLayout from "@/layouts/BasicLayout.vue"; import { apiClient } from "@/utils/api-client"; import { VButton, VSpace, VTabbar, VAvatar } from "@halo-dev/components"; -import { computed, onMounted, provide, ref, watch } from "vue"; +import { computed, onMounted, provide, ref, watch, type Ref } from "vue"; import { useRoute, useRouter } from "vue-router"; -import type { User } from "@halo-dev/api-client"; +import type { DetailedUser } from "@halo-dev/api-client"; import UserEditingModal from "../components/UserEditingModal.vue"; import UserPasswordChangeModal from "../components/UserPasswordChangeModal.vue"; import { usePermission } from "@/utils/permission"; @@ -26,7 +26,7 @@ const tabs = [ // }, ]; -const user = ref(); +const user = ref(); const loading = ref(); const editingModal = ref(false); const passwordChangeModal = ref(false); @@ -40,7 +40,7 @@ const handleFetchUser = async () => { const { data } = await apiClient.user.getCurrentUserDetail(); user.value = data; } else { - const { data } = await apiClient.extension.user.getv1alpha1User({ + const { data } = await apiClient.user.getUserDetail({ name: params.name as string, }); user.value = data; @@ -56,10 +56,12 @@ const isCurrentUser = computed(() => { if (params.name === "-") { return true; } - return user.value?.metadata.name === userStore.currentUser?.metadata.name; + return ( + user.value?.user.metadata.name === userStore.currentUser?.metadata.name + ); }); -provide("user", user); +provide>("user", user); const activeTab = ref(); @@ -92,12 +94,12 @@ const handleTabChange = (id: string) => {
    @@ -107,8 +109,8 @@ const handleTabChange = (id: string) => {
    {

    - {{ user?.spec.displayName }} + {{ user?.user.spec.displayName }}

    - @{{ user?.metadata.name }} + @{{ user?.user.metadata.name }}
  • diff --git a/src/stores/role.ts b/src/stores/role.ts index 499f8ccd..208b976c 100644 --- a/src/stores/role.ts +++ b/src/stores/role.ts @@ -1,37 +1,12 @@ import { defineStore } from "pinia"; -import type { Role, UserPermission } from "@halo-dev/api-client"; +import type { UserPermission } from "@halo-dev/api-client"; import { ref } from "vue"; -import { apiClient } from "@/utils/api-client"; -import { roleLabels } from "@/constants/labels"; -import { rbacAnnotations } from "@/constants/annotations"; export const useRoleStore = defineStore("role", () => { - const roles = ref([]); const permissions = ref({ roles: [], uiPermissions: [], }); - async function fetchRoles() { - try { - const { data } = await apiClient.extension.role.listv1alpha1Role( - { - page: 0, - size: 0, - labelSelector: [`!${roleLabels.TEMPLATE}`], - }, - { mute: true } - ); - roles.value = data.items; - } catch (error) { - console.error("Failed to fetch roles", error); - } - } - - function getRoleDisplayName(name: string) { - const role = roles.value.find((role) => role.metadata.name === name); - return role?.metadata.annotations?.[rbacAnnotations.DISPLAY_NAME] || name; - } - - return { roles, permissions, fetchRoles, getRoleDisplayName }; + return { permissions }; }); diff --git a/src/stores/user.ts b/src/stores/user.ts index bfd85a39..d158f021 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -1,9 +1,10 @@ import { apiClient } from "@/utils/api-client"; -import type { User } from "@halo-dev/api-client"; +import type { Role, User } from "@halo-dev/api-client"; import { defineStore } from "pinia"; interface UserStoreState { currentUser?: User; + currentRoles?: Role[]; isAnonymous: boolean; loginModalVisible: boolean; } @@ -11,6 +12,7 @@ interface UserStoreState { export const useUserStore = defineStore("user", { state: (): UserStoreState => ({ currentUser: undefined, + currentRoles: [], isAnonymous: true, loginModalVisible: false, }), @@ -18,8 +20,9 @@ export const useUserStore = defineStore("user", { async fetchCurrentUser() { try { const { data } = await apiClient.user.getCurrentUserDetail(); - this.currentUser = data; - this.isAnonymous = data.metadata.name === "anonymousUser"; + this.currentUser = data.user; + this.currentRoles = data.roles; + this.isAnonymous = data.user.metadata.name === "anonymousUser"; } catch (e) { console.error("Failed to fetch current user", e); }