diff --git a/.env.development b/.env.development index 0011e520..b90d28f4 100644 --- a/.env.development +++ b/.env.development @@ -7,13 +7,13 @@ VITE_PUBLIC_PATH = / # 本地开发代理,可以解决跨域及多地址代理 # 如果接口地址匹配到,则会转发到http://localhost:3000,防止本地出现跨域问题 # 可以有多个,注意多个不能换行,否则代理将会失效 -VITE_PROXY = [] +VITE_PROXY = [["/api","https://cop-demo.szsciit.com/api"]] # 是否删除Console.log VITE_DROP_CONSOLE = false # 接口地址,如果没有跨域问题,直接在这里配置即可 -VITE_GLOB_API_URL = http://192.168.1.100:48081/admin-api +VITE_GLOB_API_URL = # 文件上传接口 可选 VITE_GLOB_UPLOAD_URL = /upload diff --git a/src/api/base/user/index.ts b/src/api/base/user/index.ts index 92f64c09..8235bbac 100644 --- a/src/api/base/user/index.ts +++ b/src/api/base/user/index.ts @@ -4,13 +4,23 @@ import type { ErrorMessageMode } from '@/types/axios' export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal') { return defHttp.post({ - url: '/auth/login', - params, + url: '/api/deframe-auth/oauth/token', + params: { + username: params.username, + password: params.password, + grant_type: 'captcha', + scope: 'all', + type: 'account', + }, headers: { - 'tenant-id': '000000', + 'Tenant-Id': params.tenantId, + 'Captcha-Key': params.captchaKey, + 'Captcha-Code': params.captchaCode, }, }, { errorMessageMode: mode, + joinParamsToUrl: true, + isTransformResponse: false, }) } @@ -22,8 +32,43 @@ export function getUserInfo() { }) } +export interface __MenuItem { + id: string + parentId: string + code: string + name: string + alias: string + path: string + source: string + sort: number + category: number + action: number + children?: __MenuItem[] +} + +export function getUserRouters() { + return defHttp.get<__MenuItem[]>({ + url: '/api/deframe-system/menu/routes', + }) +} + +export function getUserButtons() { + return defHttp.get({ + url: '/api/deframe-system/menu/buttons', + }) +} + export function doLogout() { return defHttp.post({ url: '/auth/logout', }) } + +export function getLoginCaptcha() { + return defHttp.get<{ image: string, key: string }>({ + url: '/api/deframe-auth/oauth/captcha', + }, { + isTransformResponse: false, + withoutAuth: true, + }) +} diff --git a/src/api/base/user/types.ts b/src/api/base/user/types.ts index d5dc3837..a5edfdcd 100644 --- a/src/api/base/user/types.ts +++ b/src/api/base/user/types.ts @@ -3,13 +3,15 @@ import type { MenuItem } from '@/api/system/menu/types' export interface LoginParams { username: string password: string + tenantId: string + captchaKey: string + captchaCode: string } -export interface LoginResult { +export interface LoginResult extends User { userId: string - accessToken: string - refreshToken: string - expiresTime: number + access_token: string + refresh_token: string } export interface UserInfo { @@ -19,14 +21,12 @@ export interface UserInfo { } export interface User { - id: string - tenantId: string + user_id: string + tenant_id: string account: string - realName: string + real_name: string + nick_name: string avatar?: string - email?: string - mobile?: string - remark?: string - deptId: string - roleId: string + role_id: string + role_name: string } diff --git a/src/layouts/default/header/components/lock/LockModal.vue b/src/layouts/default/header/components/lock/LockModal.vue index 61a2445d..af2092b2 100644 --- a/src/layouts/default/header/components/lock/LockModal.vue +++ b/src/layouts/default/header/components/lock/LockModal.vue @@ -13,7 +13,7 @@ const { t } = useI18n() const userStore = useUserStore() const lockStore = useLockStore() -const getRealName = computed(() => userStore.getUserInfo?.user.realName) +const getRealName = computed(() => userStore.getUserInfo?.user.real_name) const [register, { closeModal }] = useModalInner() const [registerForm, { validateFields, resetFields }] = useForm({ diff --git a/src/layouts/default/header/components/user-dropdown/index.vue b/src/layouts/default/header/components/user-dropdown/index.vue index 571cfcc4..ef7fb05d 100644 --- a/src/layouts/default/header/components/user-dropdown/index.vue +++ b/src/layouts/default/header/components/user-dropdown/index.vue @@ -32,8 +32,8 @@ const { getShowDoc, getUseLockPage } = useHeaderSetting() const userStore = useUserStore() const getUserInfo = computed(() => { - const { realName = '', avatar } = userStore.getUserInfo.user || {} - return { realName, avatar: avatar || headerImg } + const { real_name = '', avatar } = userStore.getUserInfo.user || {} + return { real_name, avatar: avatar || headerImg } }) const [register, { openModal }] = useModal() @@ -76,7 +76,7 @@ function handleMenuClick(e: MenuInfo) { - {{ getUserInfo.realName }} + {{ getUserInfo.real_name }} diff --git a/src/router/guard/permissionGuard.ts b/src/router/guard/permissionGuard.ts index 3302c6dd..aabf7d51 100644 --- a/src/router/guard/permissionGuard.ts +++ b/src/router/guard/permissionGuard.ts @@ -6,7 +6,9 @@ import { PageEnum } from '@/enums/pageEnum' import { useUserStoreWithOut } from '@/store/modules/user' import { PAGE_NOT_FOUND_ROUTE } from '@/router/routes/basic' -import { useSystemEnumStoreWithOut } from '@/store/modules/systemEnum' +import { getAuthCache } from '@/utils/auth' +import { USER_INFO_KEY } from '@/enums/cacheEnum' +import type { UserInfo } from '@/api/base/user/types' // import { RootRoute } from '@/router/routes' @@ -19,7 +21,6 @@ const whitePathList: PageEnum[] = [LOGIN_PATH] export function createPermissionGuard(router: Router) { const userStore = useUserStoreWithOut() const permissionStore = usePermissionStoreWithOut() - const systemEnumStore = useSystemEnumStoreWithOut() router.beforeEach(async (to, from, next) => { // if ( @@ -33,13 +34,14 @@ export function createPermissionGuard(router: Router) { // } const token = userStore.getAccessToken + const userInfo = getAuthCache(USER_INFO_KEY) as UserInfo // Whitelist can be directly entered if (whitePathList.includes(to.path as PageEnum)) { if (to.path === LOGIN_PATH && token) { const isSessionTimeout = userStore.getSessionTimeout try { - await userStore.afterLoginAction() + await userStore.afterLoginAction(false, userInfo?.user) if (!isSessionTimeout) { next((to.query?.redirect as string) || '/') return @@ -80,13 +82,10 @@ export function createPermissionGuard(router: Router) { return } - if (!systemEnumStore.initialized) - systemEnumStore.initialize() - // get userinfo while last fetch time is empty if (userStore.getLastUpdateTime === 0) { try { - await userStore.getUserInfoAction() + await userStore.getUserInfoAction(userInfo?.user) } catch (err) { next() diff --git a/src/store/modules/lock.ts b/src/store/modules/lock.ts index 4b683466..b491f15b 100644 --- a/src/store/modules/lock.ts +++ b/src/store/modules/lock.ts @@ -1,5 +1,6 @@ import { defineStore } from 'pinia' -import { useUserStore } from './user' + +// import { useUserStore } from './user' import type { LockInfo } from '@/types/store' import { LOCK_INFO_KEY } from '@/enums/cacheEnum' @@ -29,7 +30,7 @@ export const useLockStore = defineStore('app-lock', { }, // Unlock async unLock(password?: string) { - const userStore = useUserStore() + // const userStore = useUserStore() if (this.lockInfo?.pwd === password) { this.resetLockInfo() return true @@ -37,17 +38,17 @@ export const useLockStore = defineStore('app-lock', { const tryLogin = async () => { // TODO 滑块验证码 try { - const username = userStore.getUserInfo?.user.realName - const res = await userStore.login({ - username, - password: password!, - goHome: false, - mode: 'none', - }) - if (res) - this.resetLockInfo() + // const username = userStore.getUserInfo?.user.real_name + // const res = await userStore.login({ + // username, + // password: password!, + // goHome: false, + // mode: 'none', + // }) + // if (res) + // this.resetLockInfo() - return res + // return res } catch (error) { return false diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 0ead3ce1..2e0870fe 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -13,8 +13,10 @@ import { usePermissionStore } from '@/store/modules/permission' import { useI18n } from '@/hooks/web/useI18n' import { useMessage } from '@/hooks/web/useMessage' import { getAuthCache, setAuthCache, setTenantId } from '@/utils/auth' -import { doLogout, getUserInfo, loginApi } from '@/api/base/user' -import type { LoginParams, UserInfo } from '@/api/base/user/types' +import type { __MenuItem } from '@/api/base/user' +import { doLogout, getUserButtons, getUserRouters, loginApi } from '@/api/base/user' +import type { LoginParams, User, UserInfo } from '@/api/base/user/types' +import type { MenuItem } from '@/api/system/menu/types' interface UserState { userInfo: Nullable @@ -98,22 +100,22 @@ export const useUserStore = defineStore('app-user', { try { const { goHome = true, mode, ...loginParams } = params const data = await loginApi(loginParams, mode) - const { accessToken, refreshToken } = data + const { access_token, refresh_token, ...user } = data // save token - this.setAccessToken(accessToken) - this.setRefreshToken(refreshToken) - return this.afterLoginAction(goHome) + this.setAccessToken(access_token) + this.setRefreshToken(refresh_token) + return this.afterLoginAction(goHome, user) } catch (error) { return Promise.reject(error) } }, - async afterLoginAction(goHome?: boolean): Promise { + async afterLoginAction(goHome?: boolean, user?: User): Promise { if (!this.getAccessToken) return null // get user info - const userInfo = await this.getUserInfoAction() + const userInfo = await this.getUserInfoAction(user!) const sessionTimeout = this.sessionTimeout if (sessionTimeout) { @@ -136,12 +138,45 @@ export const useUserStore = defineStore('app-user', { } return userInfo }, - async getUserInfoAction(): Promise { + async getUserInfoAction(user: User): Promise { if (!this.getAccessToken) return null - const userInfo = await getUserInfo() - setTenantId(userInfo.user.tenantId) + function normalizeMenus(__menus: __MenuItem[]): MenuItem[] { + const menus: MenuItem[] = [] + for (let i = 0; i < __menus.length; i++) { + const __menu = __menus[i] + menus.push({ + id: __menu.id, + parentId: __menu.parentId, + name: __menu.name, + component: `${__menu.path}.vue`, + // componentName?: string + path: __menu.path, + icon: __menu.source, + sort: __menu.sort, + children: __menu.children ? normalizeMenus(__menu.children) : [], + code: __menu.code, + type: 1, + visible: 1, + keepAlive: 0, + }) + } + return menus + } + + let userInfo: UserInfo | null = null + try { + const [menus, buttons] = await Promise.all([ + getUserRouters(), + getUserButtons(), + ]) + userInfo = { menus: normalizeMenus(menus), buttons, user } + } + catch { + return null + } + setTenantId(userInfo.user.tenant_id) usePermissionStore().changePermissionCode(userInfo.buttons) this.setUserInfo(userInfo) return userInfo diff --git a/src/types/axios.d.ts b/src/types/axios.d.ts index 03a19c2f..2a1f4109 100644 --- a/src/types/axios.d.ts +++ b/src/types/axios.d.ts @@ -28,6 +28,7 @@ export interface RequestOptions { withToken?: boolean // 请求重试机制 retryRequest?: RetryRequest + withoutAuth?: boolean } export interface RetryRequest { diff --git a/src/utils/http/axios/index.ts b/src/utils/http/axios/index.ts index 3c38e8b0..f3e778f0 100644 --- a/src/utils/http/axios/index.ts +++ b/src/utils/http/axios/index.ts @@ -4,6 +4,7 @@ import type { AxiosInstance, AxiosResponse } from 'axios' import { clone } from 'lodash-es' import axios from 'axios' +import CryptoJS from 'crypto-js' import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform' import { VAxios } from './Axios' import { checkStatus } from './checkStatus' @@ -27,6 +28,8 @@ const { createMessage, createErrorModal, createSuccessModal } = useMessage() // 请求白名单,无须token的接口 const whiteList: string[] = ['/login', '/refresh-token'] +const auth = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse('cop_boss:cop_boss_secret')) + /** * @description: 数据处理,方便区分多种处理方式 */ @@ -195,15 +198,18 @@ const transform: AxiosTransform = { const token = getAccessToken() if (token && !isToken) { // jwt token - (config as Recordable).headers.Authorization = options.authenticationScheme + (config as Recordable).headers['DEFrame-Auth'] = options.authenticationScheme ? `${options.authenticationScheme} ${token}` - : token + : `bearer ${token}` } // 设置租户 const tenantId = getTenantId() if (tenantId) config.headers['tenant-id'] = tenantId + if (!(config as any).requestOptions.withoutAuth) + config.headers.Authorization = `Basic ${auth}` + return config }, diff --git a/src/views/base/lock/LockPage.vue b/src/views/base/lock/LockPage.vue index b24ebb55..2516d7dd 100644 --- a/src/views/base/lock/LockPage.vue +++ b/src/views/base/lock/LockPage.vue @@ -85,7 +85,7 @@ function handleShowForm(show = false) {

- {{ userinfo.user.realName }} + {{ userinfo.user.real_name }}

diff --git a/src/views/base/login/LoginForm.vue b/src/views/base/login/LoginForm.vue index 64d78615..3752a4d9 100644 --- a/src/views/base/login/LoginForm.vue +++ b/src/views/base/login/LoginForm.vue @@ -1,12 +1,17 @@