From 4cd892e288c08b04f038bf6034c14ec022c0e919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gyq=E7=81=AC=E6=98=8E?= Date: Thu, 5 Dec 2024 07:54:05 +0000 Subject: [PATCH 001/153] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E9=85=8D=E7=BD=AE=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/apis/auth/type.ts | 1 + src/apis/common/captcha.ts | 5 + src/apis/system/type.ts | 5 + src/views/login/components/account/index.vue | 56 ++++--- .../config/components/CaptchaSetting.vue | 151 ++++++++++++++++++ src/views/system/config/index.vue | 5 + 7 files changed, 204 insertions(+), 20 deletions(-) create mode 100644 src/views/system/config/components/CaptchaSetting.vue diff --git a/package.json b/package.json index 42f3b080..ecb43178 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "version": "3.4.0", "private": "true", "scripts": { + "bootstrap": "pnpm install --registry=https://registry.npmmirror.com", "dev": "vite --host", "build": "vue-tsc --noEmit && vite build", "build:test": "vue-tsc --noEmit && vite build --mode test", diff --git a/src/apis/auth/type.ts b/src/apis/auth/type.ts index 578010cd..b154ea47 100644 --- a/src/apis/auth/type.ts +++ b/src/apis/auth/type.ts @@ -45,6 +45,7 @@ export interface RouteItem { export interface AccountLoginReq { username: string password: string + unCaptcha: boolean captcha: string uuid: string } diff --git a/src/apis/common/captcha.ts b/src/apis/common/captcha.ts index 29ac1cba..5887f011 100644 --- a/src/apis/common/captcha.ts +++ b/src/apis/common/captcha.ts @@ -5,6 +5,11 @@ export type * from './type' const BASE_URL = '/captcha' +/** @desc 获取图片验证码 */ +export function getCaptchaConfig() { + return http.get(`${BASE_URL}/config`) +} + /** @desc 获取图片验证码 */ export function getImageCaptcha() { return http.get(`${BASE_URL}/image`) diff --git a/src/apis/system/type.ts b/src/apis/system/type.ts index c5fb7a68..96e48d6f 100644 --- a/src/apis/system/type.ts +++ b/src/apis/system/type.ts @@ -316,6 +316,11 @@ export interface SecurityConfig { PASSWORD_REQUIRE_SYMBOLS: OptionResp } +/** 安全配置类型 */ +export interface CaptchaSetting { + NEED_CAPTCHA: OptionResp +} + /** 绑定三方账号信息 */ export interface BindSocialAccountRes { source: string diff --git a/src/views/login/components/account/index.vue b/src/views/login/components/account/index.vue index 96e6c1a3..3590e4f1 100644 --- a/src/views/login/components/account/index.vue +++ b/src/views/login/components/account/index.vue @@ -1,18 +1,18 @@ diff --git a/src/views/system/config/components/CaptchaSetting.vue b/src/views/system/config/components/CaptchaSetting.vue new file mode 100644 index 00000000..5c04e79d --- /dev/null +++ b/src/views/system/config/components/CaptchaSetting.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue index 3b4541fb..85089511 100644 --- a/src/views/system/config/index.vue +++ b/src/views/system/config/index.vue @@ -15,6 +15,9 @@ + + + @@ -27,6 +30,7 @@ import { useRoute, useRouter } from 'vue-router' import BasicSetting from './components/BasicSetting.vue' import MailSetting from './components/MailSetting.vue' import SecuritySetting from './components/SecuritySetting.vue' +import LoginSetting from './components/CaptchaSetting.vue' defineOptions({ name: 'SystemConfig' }) @@ -34,6 +38,7 @@ const PanMap: Record = { 1: BasicSetting, 2: MailSetting, 3: SecuritySetting, + 4: LoginSetting, } const route = useRoute() -- Gitee From 51a21688223346877f00f5142e277682e5774158 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Thu, 5 Dec 2024 19:26:23 +0800 Subject: [PATCH 002/153] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=AA=8C=E8=AF=81=E7=A0=81=E5=BC=80=E5=85=B3=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/auth/type.ts | 1 - src/apis/common/captcha.ts | 5 - src/apis/common/type.ts | 1 + src/apis/system/type.ts | 28 ++--- src/views/login/components/account/index.vue | 63 +++++------ .../{CaptchaSetting.vue => LoginSetting.vue} | 107 +++++++++--------- .../system/config/components/MailSetting.vue | 16 ++- src/views/system/config/index.vue | 16 +-- 8 files changed, 114 insertions(+), 123 deletions(-) rename src/views/system/config/components/{CaptchaSetting.vue => LoginSetting.vue} (50%) diff --git a/src/apis/auth/type.ts b/src/apis/auth/type.ts index b154ea47..578010cd 100644 --- a/src/apis/auth/type.ts +++ b/src/apis/auth/type.ts @@ -45,7 +45,6 @@ export interface RouteItem { export interface AccountLoginReq { username: string password: string - unCaptcha: boolean captcha: string uuid: string } diff --git a/src/apis/common/captcha.ts b/src/apis/common/captcha.ts index 5887f011..29ac1cba 100644 --- a/src/apis/common/captcha.ts +++ b/src/apis/common/captcha.ts @@ -5,11 +5,6 @@ export type * from './type' const BASE_URL = '/captcha' -/** @desc 获取图片验证码 */ -export function getCaptchaConfig() { - return http.get(`${BASE_URL}/config`) -} - /** @desc 获取图片验证码 */ export function getImageCaptcha() { return http.get(`${BASE_URL}/image`) diff --git a/src/apis/common/type.ts b/src/apis/common/type.ts index 90f23cc8..7d5db76c 100644 --- a/src/apis/common/type.ts +++ b/src/apis/common/type.ts @@ -3,6 +3,7 @@ export interface ImageCaptchaResp { uuid: string img: string expireTime: number + isEnabled: boolean } /** 仪表盘公告类型 */ diff --git a/src/apis/system/type.ts b/src/apis/system/type.ts index 96e48d6f..bcc9ba5c 100644 --- a/src/apis/system/type.ts +++ b/src/apis/system/type.ts @@ -293,17 +293,6 @@ export interface SiteConfig { SITE_BEIAN: OptionResp } -/** 邮箱配置类型 */ -export interface MailConfig { - MAIL_PROTOCOL: OptionResp - MAIL_HOST: OptionResp - MAIL_PORT: OptionResp - MAIL_USERNAME: OptionResp - MAIL_PASSWORD: OptionResp - MAIL_SSL_ENABLED: OptionResp - MAIL_SSL_PORT: OptionResp -} - /** 安全配置类型 */ export interface SecurityConfig { PASSWORD_ERROR_LOCK_COUNT: OptionResp @@ -316,9 +305,20 @@ export interface SecurityConfig { PASSWORD_REQUIRE_SYMBOLS: OptionResp } -/** 安全配置类型 */ -export interface CaptchaSetting { - NEED_CAPTCHA: OptionResp +/** 邮箱配置类型 */ +export interface MailConfig { + MAIL_PROTOCOL: OptionResp + MAIL_HOST: OptionResp + MAIL_PORT: OptionResp + MAIL_USERNAME: OptionResp + MAIL_PASSWORD: OptionResp + MAIL_SSL_ENABLED: OptionResp + MAIL_SSL_PORT: OptionResp +} + +/** 登录配置类型 */ +export interface LoginConfig { + LOGIN_CAPTCHA_ENABLED: OptionResp } /** 绑定三方账号信息 */ diff --git a/src/views/login/components/account/index.vue b/src/views/login/components/account/index.vue index 3590e4f1..af9a88ff 100644 --- a/src/views/login/components/account/index.vue +++ b/src/views/login/components/account/index.vue @@ -1,18 +1,23 @@ diff --git a/src/views/system/config/components/CaptchaSetting.vue b/src/views/system/config/components/LoginSetting.vue similarity index 50% rename from src/views/system/config/components/CaptchaSetting.vue rename to src/views/system/config/components/LoginSetting.vue index 5c04e79d..9cee395e 100644 --- a/src/views/system/config/components/CaptchaSetting.vue +++ b/src/views/system/config/components/LoginSetting.vue @@ -1,53 +1,44 @@ diff --git a/src/views/system/client/ClientDetailDrawer.vue b/src/views/system/client/ClientDetailDrawer.vue new file mode 100644 index 00000000..046a3e1d --- /dev/null +++ b/src/views/system/client/ClientDetailDrawer.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/src/views/system/client/index.vue b/src/views/system/client/index.vue new file mode 100644 index 00000000..0c68e0fb --- /dev/null +++ b/src/views/system/client/index.vue @@ -0,0 +1,219 @@ + + + + + -- Gitee From f0dff8b7537d5c91eb2dc67242a4a31a5649eaae Mon Sep 17 00:00:00 2001 From: Charles7c Date: Fri, 27 Dec 2024 00:22:37 +0800 Subject: [PATCH 027/153] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/auth/index.ts | 2 +- src/apis/auth/type.ts | 8 ++++---- src/stores/modules/user.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/apis/auth/index.ts b/src/apis/auth/index.ts index 46957578..bde50400 100644 --- a/src/apis/auth/index.ts +++ b/src/apis/auth/index.ts @@ -42,5 +42,5 @@ export const getUserInfo = () => { /** @desc 获取路由信息 */ export const getUserRoute = () => { - return http.get(`${BASE_URL}/route`) + return http.get(`${BASE_URL}/user/route`) } diff --git a/src/apis/auth/type.ts b/src/apis/auth/type.ts index a8a42e49..09afcea4 100644 --- a/src/apis/auth/type.ts +++ b/src/apis/auth/type.ts @@ -43,10 +43,10 @@ export interface RouteItem { /** 认证类型 */ export enum AuthTypeEnum { - ACCOUNT = 'account', - PHONE = 'phone', - EMAIL = 'email', - SOCIAL_AUTH = 'socialAuth', + ACCOUNT = 'ACCOUNT', + PHONE = 'PHONE', + EMAIL = 'EMAIL', + SOCIAL = 'SOCIAL', } export interface AuthReq { clientId: string diff --git a/src/stores/modules/user.ts b/src/stores/modules/user.ts index c8e58954..6964ee73 100644 --- a/src/stores/modules/user.ts +++ b/src/stores/modules/user.ts @@ -72,7 +72,7 @@ const storeSetup = () => { // 三方账号登录 const socialLogin = async (source: string, req: any) => { - const res = await socialLoginApi({ ...req, source, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeEnum.SOCIAL_AUTH }) + const res = await socialLoginApi({ ...req, source, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeEnum.SOCIAL }) setToken(res.data.token) token.value = res.data.token } -- Gitee From 6ff307251fd1fcd69347d300533f1c5724add29f Mon Sep 17 00:00:00 2001 From: Charles7c Date: Fri, 27 Dec 2024 20:29:59 +0800 Subject: [PATCH 028/153] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E5=8F=8A=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.test | 2 +- src/apis/auth/index.ts | 2 +- src/apis/auth/type.ts | 4 +- src/apis/system/client.ts | 72 +++----------- src/apis/system/type.ts | 81 ++++++++++------ src/stores/modules/user.ts | 6 +- src/views/code/generator/GenConfigDrawer.vue | 3 - src/views/login/components/account/index.vue | 6 +- src/views/login/components/email/index.vue | 4 +- src/views/login/components/phone/index.vue | 4 +- .../operation/OperationLogDetailDrawer.vue | 4 +- src/views/open/app/AppDetailDrawer.vue | 4 +- src/views/system/client/ClientAddModal.vue | 37 +++++--- .../system/client/ClientDetailDrawer.vue | 12 +-- src/views/system/client/index.vue | 95 +++++++++---------- src/views/system/user/UserAddDrawer.vue | 8 -- src/views/system/user/UserUpdateRoleModal.vue | 1 - 17 files changed, 155 insertions(+), 190 deletions(-) diff --git a/.env.test b/.env.test index 782fac20..5e7189ff 100644 --- a/.env.test +++ b/.env.test @@ -19,4 +19,4 @@ VITE_OPEN_DEVTOOLS = true VITE_APP_SETTING = false # 客户端ID -VITE_CLIENT_ID = '8ed5c8f9-555a-4961-ab66-9b87ddc4e3d0' \ No newline at end of file +VITE_CLIENT_ID = 'ef51c9a3e9046c4f2ea45142c8a8344a' diff --git a/src/apis/auth/index.ts b/src/apis/auth/index.ts index bde50400..6b7cd93b 100644 --- a/src/apis/auth/index.ts +++ b/src/apis/auth/index.ts @@ -27,7 +27,7 @@ export function socialLogin(req: any) { /** @desc 三方账号登录授权 */ export function socialAuth(source: string) { - return http.get(`/oauth/${source}`) + return http.get(`${BASE_URL}/${source}`) } /** @desc 退出登录 */ diff --git a/src/apis/auth/type.ts b/src/apis/auth/type.ts index 09afcea4..7b9b9ce9 100644 --- a/src/apis/auth/type.ts +++ b/src/apis/auth/type.ts @@ -49,8 +49,8 @@ export enum AuthTypeEnum { SOCIAL = 'SOCIAL', } export interface AuthReq { - clientId: string - authType: string + clientId?: string + authType?: string } /** 账号登录请求参数 */ diff --git a/src/apis/system/client.ts b/src/apis/system/client.ts index 25b5fc2c..592167fd 100644 --- a/src/apis/system/client.ts +++ b/src/apis/system/client.ts @@ -1,77 +1,31 @@ +import type * as T from './type' import http from '@/utils/http' -const BASE_URL = '/system/client' +export type * from './type' -export interface ClientResp { - id: string - clientId: string - clientKey: string - clientSecret: string - authType: string - clientType: string - activeTimeout: string - timeout: string - status: string - createUser: string - createTime: string - updateUser: string - updateTime: string - createUserString: string - updateUserString: string -} -export interface ClientDetailResp { - id: string - clientId: string - clientKey: string - clientSecret: string - authType: string - clientType: string - activeTimeout: string - timeout: string - status: string - createUser: string - createTime: string - updateUser: string - updateTime: string - createUserString: string - updateUserString: string -} -export interface ClientQuery { - clientKey: string - clientSecret: string - authType: string[] - clientType: string - status: string - sort: Array -} -export interface ClientPageQuery extends ClientQuery, PageQuery {} +const BASE_URL = '/system/client' -/** @desc 查询系统授权列表 */ -export function listClient(query: ClientPageQuery) { - return http.get>(`${BASE_URL}`, query) +/** @desc 查询客户端列表 */ +export function listClient(query: T.ClientPageQuery) { + return http.get>(`${BASE_URL}`, query) } -/** @desc 查询系统授权详情 */ +/** @desc 查询客户端详情 */ export function getClient(id: string) { - return http.get(`${BASE_URL}/${id}`) + return http.get(`${BASE_URL}/${id}`) } -/** @desc 新增系统授权 */ +/** @desc 新增客户端 */ export function addClient(data: any) { return http.post(`${BASE_URL}`, data) } -/** @desc 修改系统授权 */ +/** @desc 修改客户端 */ export function updateClient(data: any, id: string) { return http.put(`${BASE_URL}/${id}`, data) } -/** @desc 删除系统授权 */ -export function deleteClient(id: string) { - return http.del(`${BASE_URL}/${id}`) -} - -/** @desc 导出系统授权 */ -export function exportClient(query: ClientQuery) { - return http.download(`${BASE_URL}/export`, query) +/** @desc 删除客户端 */ +export function deleteClient(ids: string | Array) { + return http.del(`${BASE_URL}/${ids}`) } diff --git a/src/apis/system/type.ts b/src/apis/system/type.ts index bcc9ba5c..bce9da26 100644 --- a/src/apis/system/type.ts +++ b/src/apis/system/type.ts @@ -1,4 +1,4 @@ -/** 系统用户类型 */ +/** 用户类型 */ export interface UserResp { id: string username: string @@ -20,11 +20,9 @@ export interface UserResp { roleNames: Array disabled: boolean } - export type UserDetailResp = UserResp & { pwdResetTime?: string } - export interface UserImportResp { importKey: string totalRows: number @@ -33,7 +31,6 @@ export interface UserImportResp { duplicateEmailRows: number duplicatePhoneRows: number } - export interface UserQuery { description?: string status?: number @@ -42,10 +39,9 @@ export interface UserQuery { sort: Array userIds?: Array } - export interface UserPageQuery extends UserQuery, PageQuery {} -/** 系统角色类型 */ +/** 角色类型 */ export interface RoleResp { id: string name: string @@ -60,22 +56,19 @@ export interface RoleResp { updateTime: string disabled: boolean } - export type RoleDetailResp = RoleResp & { menuIds: Array deptIds: Array menuCheckStrictly: boolean deptCheckStrictly: boolean } - export interface RoleQuery { description?: string sort: Array } - export interface RolePageQuery extends RoleQuery, PageQuery {} -/** 系统菜单类型 */ +/** 菜单类型 */ export interface MenuResp { id: string title: string @@ -98,13 +91,12 @@ export interface MenuResp { updateTime: string children: MenuResp[] } - export interface MenuQuery { title?: string status?: number } -/** 系统部门类型 */ +/** 部门类型 */ export interface DeptResp { id: string name: string @@ -119,13 +111,12 @@ export interface DeptResp { parentId: string children: DeptResp[] } - export interface DeptQuery { description?: string status?: number } -/** 系统字典类型 */ +/** 字典类型 */ export interface DictResp { id: string name: string @@ -137,12 +128,10 @@ export interface DictResp { updateUserString: string updateTime: string } - export interface DictQuery { description?: string sort: Array } - export interface DictItemResp { id: string label: string @@ -157,18 +146,16 @@ export interface DictItemResp { updateUserString: string updateTime: string } - export interface DictItemQuery { description?: string status?: number sort: Array dictId: string } - export interface DictItemPageQuery extends DictItemQuery, PageQuery { } -/** 系统公告类型 */ +/** 公告类型 */ export interface NoticeResp { id?: string title?: string @@ -184,17 +171,15 @@ export interface NoticeResp { updateUserString?: string updateTime?: string } - export interface NoticeQuery { title?: string type?: string sort: Array } - export interface NoticePageQuery extends NoticeQuery, PageQuery { } -/** 系统文件类型 */ +/** 文件类型 */ export interface FileItem { id: string name: string @@ -211,7 +196,6 @@ export interface FileItem { updateUserString: string updateTime: string } - /** 文件资源统计信息 */ export interface FileStatisticsResp { type: string @@ -220,17 +204,15 @@ export interface FileStatisticsResp { unit: string data: Array } - export interface FileQuery { name?: string type?: string sort: Array } - export interface FilePageQuery extends FileQuery, PageQuery { } -/** 系统存储类型 */ +/** 存储类型 */ export interface StorageResp { id: string name: string @@ -250,16 +232,59 @@ export interface StorageResp { updateUserString: string updateTime: string } - export interface StorageQuery { description?: string status?: number sort: Array } - export interface StoragePageQuery extends StorageQuery, PageQuery { } +/** 客户端类型 */ +export interface ClientResp { + id: string + clientId: string + clientKey: string + clientSecret: string + authType: string + clientType: string + activeTimeout: string + timeout: string + status: string + createUser: string + createTime: string + updateUser: string + updateTime: string + createUserString: string + updateUserString: string +} +export interface ClientDetailResp { + id: string + clientId: string + clientKey: string + clientSecret: string + authType: string + clientType: string + activeTimeout: string + timeout: string + status: string + createUser: string + createTime: string + updateUser: string + updateTime: string + createUserString: string + updateUserString: string +} +export interface ClientQuery { + clientKey: string + clientSecret: string + authType: string[] + clientType: string + status: string + sort: Array +} +export interface ClientPageQuery extends ClientQuery, PageQuery {} + /** 系统参数类型 */ export interface OptionResp { id: string diff --git a/src/stores/modules/user.ts b/src/stores/modules/user.ts index 6964ee73..7599a26c 100644 --- a/src/stores/modules/user.ts +++ b/src/stores/modules/user.ts @@ -51,21 +51,21 @@ const storeSetup = () => { // 登录 const accountLogin = async (req: AccountLoginReq) => { - const res = await accountLoginApi(req) + const res = await accountLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeEnum.ACCOUNT }) setToken(res.data.token) token.value = res.data.token } // 邮箱登录 const emailLogin = async (req: EmailLoginReq) => { - const res = await emailLoginApi(req) + const res = await emailLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeEnum.EMAIL }) setToken(res.data.token) token.value = res.data.token } // 手机号登录 const phoneLogin = async (req: PhoneLoginReq) => { - const res = await phoneLoginApi(req) + const res = await phoneLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeEnum.PHONE }) setToken(res.data.token) token.value = res.data.token } diff --git a/src/views/code/generator/GenConfigDrawer.vue b/src/views/code/generator/GenConfigDrawer.vue index faae315f..69c2c302 100644 --- a/src/views/code/generator/GenConfigDrawer.vue +++ b/src/views/code/generator/GenConfigDrawer.vue @@ -154,9 +154,6 @@ const formColumns: Columns = reactive([ label: '作者名称', field: 'author', type: 'input', - props: { - placeholder: '请输入作者名称', - }, rules: [{ required: true, message: '请输入作者名称' }], }, { diff --git a/src/views/login/components/account/index.vue b/src/views/login/components/account/index.vue index 70aec322..4b5a8ca7 100644 --- a/src/views/login/components/account/index.vue +++ b/src/views/login/components/account/index.vue @@ -43,7 +43,6 @@ import { useStorage } from '@vueuse/core' import { getImageCaptcha } from '@/apis/common' import { useTabsStore, useUserStore } from '@/stores' import { encryptByRsa } from '@/utils/encrypt' -import { AuthTypeEnum } from '@/apis' const loginConfig = useStorage('login-config', { rememberMe: true, @@ -120,8 +119,6 @@ const handleLogin = async () => { password: encryptByRsa(form.password) || '', captcha: form.captcha, uuid: form.uuid, - clientId: import.meta.env.VITE_CLIENT_ID, - authType: AuthTypeEnum.ACCOUNT, }) tabsStore.reset() const { redirect, ...othersQuery } = router.currentRoute.value.query @@ -135,8 +132,7 @@ const handleLogin = async () => { loginConfig.value.username = rememberMe ? form.username : '' Message.success('欢迎使用') } catch (error) { - console.log('error', error) - + console.error(error) getCaptcha() form.captcha = '' } finally { diff --git a/src/views/login/components/email/index.vue b/src/views/login/components/email/index.vue index 17ef2844..55f7a888 100644 --- a/src/views/login/components/email/index.vue +++ b/src/views/login/components/email/index.vue @@ -40,7 +40,7 @@ diff --git a/src/components/SplitPanel/index.vue b/src/components/SplitPanel/index.vue new file mode 100644 index 00000000..d46da105 --- /dev/null +++ b/src/components/SplitPanel/index.vue @@ -0,0 +1,409 @@ + + + + + diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 89911ebc..604dfd6b 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -51,6 +51,7 @@ declare module 'vue' { RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SecondForm: typeof import('./../components/GenCron/CronForm/component/second-form.vue')['default'] + SplitPanel: typeof import('./../components/SplitPanel/index.vue')['default'] TextCopy: typeof import('./../components/TextCopy/index.vue')['default'] UserSelect: typeof import('./../components/UserSelect/index.vue')['default'] Verify: typeof import('./../components/Verify/index.vue')['default'] diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue index 5d6b7a49..f78bcd73 100644 --- a/src/views/system/dict/index.vue +++ b/src/views/system/dict/index.vue @@ -5,57 +5,61 @@
字典管理
- - + + + + diff --git a/src/views/system/dict/tree/index.vue b/src/views/system/dict/tree/index.vue index cfae43c6..59bc57b7 100644 --- a/src/views/system/dict/tree/index.vue +++ b/src/views/system/dict/tree/index.vue @@ -218,7 +218,7 @@ onMounted(() => { background-color: var(--color-bg-1); position: relative; height: 100%; - margin-bottom:10px; +/* margin-bottom:10px;*/ .tree { position: absolute; top: 0; diff --git a/src/views/system/user/dept/index.vue b/src/views/system/user/dept/index.vue index 89ddf201..4c169b76 100644 --- a/src/views/system/user/dept/index.vue +++ b/src/views/system/user/dept/index.vue @@ -150,7 +150,7 @@ onMounted(() => { background-color: var(--color-bg-1); position: relative; height: 100%; - margin-bottom:10px; +/* margin-bottom:10px;*/ .tree { position: absolute; top: 0; diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index 4c4b33e9..a66e3695 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -5,86 +5,90 @@
用户管理
- - + + + -- Gitee From 91092f1cf3355da69ada5fd5edd2a17b6c747d1e Mon Sep 17 00:00:00 2001 From: Charles7c Date: Thu, 2 Jan 2025 20:28:29 +0800 Subject: [PATCH 030/153] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=97=A0=E6=B3=95=E7=9B=B4=E6=8E=A5=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes continew/continew-admin#IBF2YB --- src/utils/downloadFile.ts | 50 +++++++++++++++------------------------ 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/src/utils/downloadFile.ts b/src/utils/downloadFile.ts index c979e0b2..47824b05 100644 --- a/src/utils/downloadFile.ts +++ b/src/utils/downloadFile.ts @@ -25,8 +25,9 @@ export function downloadByUrl({ }): Promise { // 是否同源 const isSameHost = new URL(url).host === location.host - return new Promise((resolve) => { + return new Promise((resolve, reject) => { if (isSameHost) { + // 同源资源,直接使用 标签下载 const link = document.createElement('a') link.href = url link.target = target @@ -49,36 +50,23 @@ export function downloadByUrl({ window.open(url, target) return resolve(true) } else { - const elink = document.createElement('a') - elink.href = url - elink.target = '_self' - elink.download = fileName as string - elink.style.display = 'none' - document.body.appendChild(elink) - elink.click() - document.body.removeChild(elink) - // const canvas = document.createElement('canvas') - // const img = document.createElement('img') - // img.setAttribute('crossOrigin', 'Anonymous') - // img.src = url - // img.onload = () => { - // canvas.width = img.width - // canvas.height = img.height - // const context = canvas.getContext('2d')! - // context.drawImage(img, 0, 0, img.width, img.height) - // // window.navigator.msSaveBlob(canvas.msToBlob(),'image.jpg'); - // // saveAs(imageDataUrl, '附件'); - // canvas.toBlob((blob) => { - // const link = document.createElement('a') - // if (!blob) return - // link.href = window.URL.createObjectURL(blob) - // link.download = fileName || getFileName(url) - // link.click() - // URL.revokeObjectURL(link.href) - // resolve(true) - // }, 'image/jpeg') - // } - // img.onerror = (e) => reject(e) + // 跨域资源,使用 fetch 获取文件并下载 + fetch(url) + .then((response) => response.blob()) + .then((blob) => { + const link = document.createElement('a') + link.href = URL.createObjectURL(blob) + link.download = fileName || getFileName(url) + link.style.display = 'none' + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + URL.revokeObjectURL(link.href) + resolve(true) + }) + .catch((err) => { + reject(err) + }) } }) } -- Gitee From aa14d6bdeaa41506664fb653f91fa3aacb6e1983 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Sat, 4 Jan 2025 19:45:44 +0800 Subject: [PATCH 031/153] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E5=AE=88=E5=8D=AB=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/guard.ts | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/router/guard.ts b/src/router/guard.ts index 8464a85f..79046a07 100644 --- a/src/router/guard.ts +++ b/src/router/guard.ts @@ -91,27 +91,21 @@ export const setupRouterGuard = (router: Router) => { next() } else { if (!hasRouteFlag) { - try { - await userStore.getInfo() - if (userStore.userInfo.pwdExpired && to.path !== '/pwdExpired') { - Message.warning('密码已过期,请修改密码') - next('/pwdExpired') - } - const accessRoutes = await routeStore.generateRoutes() - accessRoutes.forEach((route) => { - if (!isHttp(route.path)) { - router.addRoute(route) // 动态添加可访问路由表 - } - }) - hasRouteFlag = true - // 确保添加路由已完成 - // 设置 replace: true, 因此导航将不会留下历史记录 - next({ ...to, replace: true }) - } catch (error: any) { - // 过程中发生任何错误,都直接重置 Token,并重定向到登录页面 - await userStore.logoutCallBack() - next(`/login?redirect=${to.path}`) + await userStore.getInfo() + if (userStore.userInfo.pwdExpired && to.path !== '/pwdExpired') { + Message.warning('密码已过期,请修改密码') + next('/pwdExpired') } + const accessRoutes = await routeStore.generateRoutes() + accessRoutes.forEach((route) => { + if (!isHttp(route.path)) { + router.addRoute(route) // 动态添加可访问路由表 + } + }) + hasRouteFlag = true + // 确保添加路由已完成 + // 设置 replace: true, 因此导航将不会留下历史记录 + next({ ...to, replace: true }) } else { next() } -- Gitee From d3aeca81d850d4d13af7fec3c6a7a4690068200c Mon Sep 17 00:00:00 2001 From: ppxb <317842449@qq.com> Date: Sat, 4 Jan 2025 21:09:01 +0800 Subject: [PATCH 032/153] refactor: http util and route store (#43) --- package.json | 1 + pnpm-lock.yaml | 16 ++++ src/router/asyncModules.ts | 13 ++++ src/stores/modules/dict.ts | 43 ++++------- src/stores/modules/route.ts | 77 +++++++------------ src/types/global.d.ts | 6 +- src/utils/http.ts | 145 ++++++++++++++---------------------- 7 files changed, 129 insertions(+), 172 deletions(-) create mode 100644 src/router/asyncModules.ts diff --git a/package.json b/package.json index b52f2bc3..7b8d0021 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@antfu/eslint-config": "^2.16.3", "@arco-design/web-vue": "^2.56.0", "@types/crypto-js": "^4.2.2", + "@types/lodash-es": "^4.17.12", "@types/node": "^20.2.5", "@types/query-string": "^6.3.0", "@vitejs/plugin-vue": "^5.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9de94bad..78deafa2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -150,6 +150,9 @@ importers: '@types/crypto-js': specifier: ^4.2.2 version: 4.2.2 + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 '@types/node': specifier: ^20.2.5 version: 20.12.12 @@ -1155,6 +1158,12 @@ packages: '@types/linkify-it@3.0.5': resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==} + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.13': + resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} + '@types/markdown-it@13.0.9': resolution: {integrity: sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==} @@ -1455,6 +1464,7 @@ packages: acorn-import-assertions@1.9.0: resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + deprecated: package has been renamed to acorn-import-attributes peerDependencies: acorn: ^8 @@ -5703,6 +5713,12 @@ snapshots: '@types/linkify-it@3.0.5': {} + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.13 + + '@types/lodash@4.17.13': {} + '@types/markdown-it@13.0.9': dependencies: '@types/linkify-it': 3.0.5 diff --git a/src/router/asyncModules.ts b/src/router/asyncModules.ts new file mode 100644 index 00000000..4f2a4448 --- /dev/null +++ b/src/router/asyncModules.ts @@ -0,0 +1,13 @@ +type ImportVueFileType = typeof import('*.vue') +type ImportVueFileFnType = () => Promise + +const moduleFiles = import.meta.glob('@/views/**/*.vue') + +export const asyncRouteModules = Object.entries(moduleFiles).reduce((routes, [url, importFn]) => { + if (!/\/(views\/login|components)\//.test(url)) { + const path = url.replace('/src/views/', '').replace('.vue', '') + routes[path] = importFn + } + + return routes +}, {} as Recordable) diff --git a/src/stores/modules/dict.ts b/src/stores/modules/dict.ts index 58784958..d1d7fa96 100644 --- a/src/stores/modules/dict.ts +++ b/src/stores/modules/dict.ts @@ -1,51 +1,36 @@ import { defineStore } from 'pinia' -import type { DictState, LabelValueState } from '@/types/global' +import type { LabelValueState } from '@/types/global' const storeSetup = () => { - const dictData = ref([]) + const dictData = ref(new Map()) // 设置字典 - const setDict = (_code: string, items: Array) => { - if (_code !== null && _code !== '') { - dictData.value.push({ - code: _code, - items, - }) + const setDict = (code: string, items: Array) => { + if (code) { + dictData.value.set(code, items) } } // 获取字典 - const getDict = (_code: string) => { - if (_code == null || _code === '') { - return null - } - for (let i = 0; i < dictData.value.length; i += 1) { - if (dictData.value[i].code === _code) { - return dictData.value[i].items - } - } - return null + const getDict = (code: string) => { + if (!code) return null + return dictData.value.get(code) || null } // 删除字典 - const deleteDict = (_code: string) => { - let bln = false + const deleteDict = (code: string) => { try { - for (let i = 0; i < dictData.value.length; i += 1) { - if (dictData.value[i].code === _code) { - dictData.value.splice(i, 1) - return true - } - } + return dictData.value.delete(code) } catch (e) { - bln = false + return false } - return bln } + // 清空字典 const cleanDict = () => { - dictData.value = [] + dictData.value.clear() } + return { setDict, getDict, diff --git a/src/stores/modules/route.ts b/src/stores/modules/route.ts index 78a683a5..826e69f9 100644 --- a/src/stores/modules/route.ts +++ b/src/stores/modules/route.ts @@ -4,36 +4,18 @@ import type { RouteRecordRaw } from 'vue-router' import { mapTree, toTreeArray } from 'xe-utils' import { cloneDeep, omit } from 'lodash-es' import { constantRoutes, systemRoutes } from '@/router/route' -import ParentView from '@/components/ParentView/index.vue' import { type RouteItem, getUserRoute } from '@/apis' import { transformPathToName } from '@/utils' +import { asyncRouteModules } from '@/router/asyncModules' -const Layout = () => import('@/layout/index.vue') - -// 匹配views里面所有的.vue文件 -const modules = import.meta.glob('@/views/**/*.vue') - -/** 加载模块 */ -export const loadView = (view: string) => { - let res - for (const path in modules) { - const dir = path.split('views/')[1].split('.vue')[0] - if (dir === view) { - res = () => modules[path]() - } - } - return res +const layoutComponentMap = { + Layout: () => import('@/layout/index.vue'), + ParentView: () => import('@/components/ParentView/index.vue'), } /** 将component由字符串转成真正的模块 */ const transformComponentView = (component: string) => { - if (component === 'Layout') { - return Layout as never - } else if (component === 'ParentView') { - return ParentView as never - } else { - return loadView(component) as never - } + return layoutComponentMap[component as keyof typeof layoutComponentMap] || asyncRouteModules[component] } /** @@ -44,16 +26,20 @@ const transformComponentView = (component: string) => { */ const formatAsyncRoutes = (menus: RouteItem[]) => { if (!menus.length) return [] + const pathMap = new Map() - const routes = mapTree(menus, (item) => { + return mapTree(menus, (item) => { pathMap.set(item.id, item.path) - if (item.children && item.children.length) { - item.children.sort((a, b) => (a?.sort ?? 0) - (b?.sort ?? 0)) // 排序 + + if (item.children?.length) { + item.children.sort((a, b) => (a?.sort ?? 0) - (b?.sort ?? 0)) } + // 部分子菜单,例如:通知公告新增、查看详情,需要选中其父菜单 if (item.parentId && item.type === 2 && item.permission) { item.activeMenu = pathMap.get(item.parentId) } + return { path: item.path, name: item.name ?? transformPathToName(item.path), @@ -68,30 +54,24 @@ const formatAsyncRoutes = (menus: RouteItem[]) => { activeMenu: item.activeMenu, }, } - }) - return routes as RouteRecordRaw[] + }) as unknown as RouteRecordRaw[] } /** 判断路由层级是否大于 2 */ export const isMultipleRoute = (route: RouteRecordRaw) => { - const children = route.children - if (children?.length) { - // 只要有一个子路由的 children 长度大于 0,就说明是三级及其以上路由 - return children.some((child) => child.children?.length) - } - return false + return route.children?.some((child) => child.children?.length) ?? false } /** 路由降级(把三级及其以上的路由转化为二级路由) */ export const flatMultiLevelRoutes = (routes: RouteRecordRaw[]) => { - const cloneRoutes = cloneDeep(routes) - cloneRoutes.forEach((route) => { - if (isMultipleRoute(route)) { - const flatRoutes = toTreeArray(route.children) - route.children = flatRoutes.map((i) => omit(i, 'children')) as RouteRecordRaw[] + return cloneDeep(routes).map((route) => { + if (!isMultipleRoute(route)) return route + + return { + ...route, + children: toTreeArray(route.children).map((item) => omit(item, 'children')) as RouteRecordRaw[], } }) - return cloneRoutes } const storeSetup = () => { @@ -109,17 +89,12 @@ const storeSetup = () => { } // 生成路由 - const generateRoutes = (): Promise => { - return new Promise((resolve) => { - // 向后端请求路由数据 这个接口已经根据用户角色过滤了没权限的路由(后端根据用户角色过滤路由显得比较安全些) - getUserRoute().then((res) => { - const asyncRoutes = formatAsyncRoutes(res.data) - setRoutes(asyncRoutes) - const cloneRoutes = cloneDeep(asyncRoutes) - const flatRoutes = flatMultiLevelRoutes(cloneRoutes as RouteRecordRaw[]) - resolve(flatRoutes) - }) - }) + const generateRoutes = async (): Promise => { + const { data } = await getUserRoute() + const asyncRoutes = formatAsyncRoutes(data) + const flatRoutes = flatMultiLevelRoutes(cloneDeep(asyncRoutes)) + setRoutes(asyncRoutes) + return flatRoutes } return { diff --git a/src/types/global.d.ts b/src/types/global.d.ts index 47168f47..45ece5ae 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -14,10 +14,8 @@ export interface LabelValueState { extra?: string } -/** 字典类型 */ -export interface DictState { - code: string - items: Array +declare global{ + type Recordable = Record } /** 状态(1:启用;2:禁用) */ diff --git a/src/utils/http.ts b/src/utils/http.ts index e87de319..8feb0d16 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -1,6 +1,6 @@ import axios from 'axios' import qs from 'query-string' -import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' +import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' import { useUserStore } from '@/stores' import { getToken } from '@/utils/auth' import modalErrorWrapper from '@/utils/modal-error-wrapper' @@ -34,6 +34,16 @@ const http: AxiosInstance = axios.create({ timeout: 30 * 1000, }) +const handleError = (msg: string) => { + if (msg.length >= 15) { + return notificationErrorWrapper(msg || '服务器端错误') + } + return messageErrorWrapper({ + content: msg || '服务器端错误', + duration: 5 * 1000, + }) +} + // 请求拦截器 http.interceptors.request.use( (config: AxiosRequestConfig) => { @@ -46,9 +56,7 @@ http.interceptors.request.use( } return config }, - (error) => { - return Promise.reject(error) - }, + (error) => Promise.reject(error), ) // 响应拦截器 @@ -56,11 +64,8 @@ http.interceptors.response.use( (response: AxiosResponse) => { const { data } = response const { success, code, msg } = data - if (response.request.responseType === 'blob') { - return response - } - // 成功 - if (success) { + + if (response.request.responseType === 'blob' || success) { return response } @@ -79,104 +84,68 @@ http.interceptors.response.use( }, }) } else { - // 如果错误信息长度过长,使用 Notification 进行提示 - if (msg.length <= 15) { - messageErrorWrapper({ - content: msg || '服务器端错误', - duration: 5 * 1000, - }) - } else { - notificationErrorWrapper(msg || '服务器端错误') - } + handleError(msg) } return Promise.reject(new Error(msg || '服务器端错误')) }, - (error) => { - const response = Object.assign({}, error.response) - response - && messageErrorWrapper({ - content: StatusCodeMessage[response.status] || '服务器暂时未响应,请刷新页面并重试。若无法解决,请联系管理员', - duration: 5 * 1000, - }) + (error: AxiosError) => { + if (!error.response) { + handleError('网络连接失败,请检查您的网络') + return Promise.reject(error) + } + const status = error.response?.status + const errorMsg = StatusCodeMessage[status] || '服务器暂时未响应,请刷新页面并重试。若无法解决,请联系管理员' + handleError(errorMsg) return Promise.reject(error) }, ) -const request = (config: AxiosRequestConfig): Promise> => { - return new Promise((resolve, reject) => { - http - .request(config) - .then((res: AxiosResponse) => resolve(res.data)) - .catch((err: { msg: string }) => reject(err)) - }) -} - -const requestNative = (config: AxiosRequestConfig): Promise => { - return new Promise((resolve, reject) => { - http - .request(config) - .then((res: AxiosResponse) => resolve(res)) - .catch((err: { msg: string }) => reject(err)) - }) -} - -const get = (url: string, params?: object, config?: AxiosRequestConfig): Promise> => { - return request({ - method: 'get', - url, - params, - paramsSerializer: (obj) => { - return qs.stringify(obj) - }, - ...config, - }) -} - -const post = (url: string, params?: object, config?: AxiosRequestConfig): Promise> => { - return request({ - method: 'post', - url, - data: params, - ...config, - }) +const request = async (config: AxiosRequestConfig): Promise> => { + return http.request(config) + .then((res: AxiosResponse) => res.data) + .catch((err: { msg: string }) => Promise.reject(err)) } -const put = (url: string, params?: object, config?: AxiosRequestConfig): Promise> => { - return request({ - method: 'put', - url, - data: params, - ...config, - }) +const requestNative = async (config: AxiosRequestConfig): Promise => { + return http.request(config) + .then((res: AxiosResponse) => res) + .catch((err: { msg: string }) => Promise.reject(err)) } -const patch = (url: string, params?: object, config?: AxiosRequestConfig): Promise> => { - return request({ - method: 'patch', - url, - data: params, - ...config, - }) +const createRequest = (method: string) => { + return (url: string, params?: object, config?: AxiosRequestConfig): Promise> => { + return request({ + method, + url, + [method === 'get' ? 'params' : 'data']: params, + ...(method === 'get' + ? { + paramsSerializer: (obj) => qs.stringify(obj), + } + : {}), + ...config, + }) + } } -const del = (url: string, params?: object, config?: AxiosRequestConfig): Promise> => { - return request({ - method: 'delete', - url, - data: params, - ...config, - }) -} const download = (url: string, params?: object, config?: AxiosRequestConfig): Promise => { return requestNative({ method: 'get', url, responseType: 'blob', params, - paramsSerializer: (obj) => { - return qs.stringify(obj) - }, + paramsSerializer: (obj) => qs.stringify(obj), ...config, }) } -export default { get, post, put, patch, del, request, requestNative, download } + +export default { + get: createRequest('get'), + post: createRequest('post'), + put: createRequest('put'), + patch: createRequest('patch'), + del: createRequest('delete'), + request, + requestNative, + download, +} -- Gitee From a93b88d0cfe1ea5f49d2a775c4d25cee2e086ffa Mon Sep 17 00:00:00 2001 From: Charles7c Date: Sun, 5 Jan 2025 19:59:59 +0800 Subject: [PATCH 033/153] =?UTF-8?q?revert:=20=E8=BF=98=E5=8E=9F=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E5=AE=88=E5=8D=AB=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/guard.ts | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/router/guard.ts b/src/router/guard.ts index 79046a07..8464a85f 100644 --- a/src/router/guard.ts +++ b/src/router/guard.ts @@ -91,21 +91,27 @@ export const setupRouterGuard = (router: Router) => { next() } else { if (!hasRouteFlag) { - await userStore.getInfo() - if (userStore.userInfo.pwdExpired && to.path !== '/pwdExpired') { - Message.warning('密码已过期,请修改密码') - next('/pwdExpired') - } - const accessRoutes = await routeStore.generateRoutes() - accessRoutes.forEach((route) => { - if (!isHttp(route.path)) { - router.addRoute(route) // 动态添加可访问路由表 + try { + await userStore.getInfo() + if (userStore.userInfo.pwdExpired && to.path !== '/pwdExpired') { + Message.warning('密码已过期,请修改密码') + next('/pwdExpired') } - }) - hasRouteFlag = true - // 确保添加路由已完成 - // 设置 replace: true, 因此导航将不会留下历史记录 - next({ ...to, replace: true }) + const accessRoutes = await routeStore.generateRoutes() + accessRoutes.forEach((route) => { + if (!isHttp(route.path)) { + router.addRoute(route) // 动态添加可访问路由表 + } + }) + hasRouteFlag = true + // 确保添加路由已完成 + // 设置 replace: true, 因此导航将不会留下历史记录 + next({ ...to, replace: true }) + } catch (error: any) { + // 过程中发生任何错误,都直接重置 Token,并重定向到登录页面 + await userStore.logoutCallBack() + next(`/login?redirect=${to.path}`) + } } else { next() } -- Gitee From 113c6e3a718f50ad5195846d4e0cc44a81950982 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Sun, 5 Jan 2025 21:07:05 +0800 Subject: [PATCH 034/153] =?UTF-8?q?style(system/dict):=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=AD=97=E5=85=B8=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/dict/tree/index.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/views/system/dict/tree/index.vue b/src/views/system/dict/tree/index.vue index 59bc57b7..296d2b5e 100644 --- a/src/views/system/dict/tree/index.vue +++ b/src/views/system/dict/tree/index.vue @@ -191,6 +191,9 @@ onMounted(() => { .arco-typography { color: rgb(var(--primary-6)); } + .action { + opacity: 1; + } } .container { -- Gitee From 4b61e4027e770b63e6301335d5add390d9afef50 Mon Sep 17 00:00:00 2001 From: KAI <1373639299@qq.com> Date: Thu, 9 Jan 2025 08:48:08 +0000 Subject: [PATCH 035/153] =?UTF-8?q?feat(system/dept):=20=E9=83=A8=E9=97=A8?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=96=B0=E5=A2=9E=E7=BB=84=E7=BB=87=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E8=A7=86=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 18 ++++++ src/apis/common/common.ts | 2 +- src/apis/system/dept.ts | 2 +- src/views/system/dept/index.vue | 102 ++++++++++++++++++++++++++++++-- 5 files changed, 119 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 7b8d0021..466ead99 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "vue-echarts": "^6.5.5", "vue-json-pretty": "^2.4.0", "vue-router": "^4.3.3", + "vue3-tree-org": "^4.2.2", "xe-utils": "^3.5.7", "xgplayer": "^2.31.6" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78deafa2..c03c6051 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -134,6 +134,9 @@ importers: vue-router: specifier: ^4.3.3 version: 4.3.3(vue@3.5.12(typescript@5.0.4)) + vue3-tree-org: + specifier: ^4.2.2 + version: 4.2.2(vue@3.5.12(typescript@5.0.4)) xe-utils: specifier: ^3.5.7 version: 3.5.26 @@ -1839,6 +1842,9 @@ packages: core-js-compat@3.37.1: resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} + core-js@3.40.0: + resolution: {integrity: sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==} + cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} @@ -4625,6 +4631,11 @@ packages: peerDependencies: typescript: '*' + vue3-tree-org@4.2.2: + resolution: {integrity: sha512-AG2SykyD6dw0jIyqBm8iuF9j9GWli6KrwudxR1RjULCCBTDFsoNm7MmP/weKT7wowN/sPk+e2RsnvEJMw2OJMw==} + peerDependencies: + vue: ^3.0.0 + vue@3.5.12: resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==} peerDependencies: @@ -6587,6 +6598,8 @@ snapshots: dependencies: browserslist: 4.23.0 + core-js@3.40.0: {} + cors@2.8.5: dependencies: object-assign: 4.1.1 @@ -9618,6 +9631,11 @@ snapshots: semver: 7.6.2 typescript: 5.0.4 + vue3-tree-org@4.2.2(vue@3.5.12(typescript@5.0.4)): + dependencies: + core-js: 3.40.0 + vue: 3.5.12(typescript@5.0.4) + vue@3.5.12(typescript@5.0.4): dependencies: '@vue/compiler-dom': 3.5.12 diff --git a/src/apis/common/common.ts b/src/apis/common/common.ts index 0c588df2..004abbc6 100644 --- a/src/apis/common/common.ts +++ b/src/apis/common/common.ts @@ -5,7 +5,7 @@ import type { LabelValueState } from '@/types/global' const BASE_URL = '/common' /** @desc 查询部门树 */ -export function listDeptTree(query: { description: string }) { +export function listDeptTree(query: { description: string | unknown }) { return http.get(`${BASE_URL}/tree/dept`, query) } diff --git a/src/apis/system/dept.ts b/src/apis/system/dept.ts index 807ec273..c591593f 100644 --- a/src/apis/system/dept.ts +++ b/src/apis/system/dept.ts @@ -32,5 +32,5 @@ export function deleteDept(id: string) { /** @desc 导出部门 */ export function exportDept(query: T.DeptQuery) { - return http.download(`${BASE_URL}/export`, query) + return http.download(`${BASE_URL}/export`, query) } diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue index 5f152e2d..92c1d898 100644 --- a/src/views/system/dept/index.vue +++ b/src/views/system/dept/index.vue @@ -1,6 +1,13 @@ - + +
+ + + + + + +
- + -- Gitee From 8c55504bf8e94ab27dddeef81dbc834eb91289a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E5=B8=86?= <201379873@qq.com> Date: Sun, 12 Jan 2025 20:30:32 +0800 Subject: [PATCH 036/153] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=E5=B7=A6?= =?UTF-8?q?=E6=A0=91=E5=8F=B3=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GiTable/index.vue | 28 +-- src/components/SplitPanel/index.vue | 222 +++++++++-------------- src/views/code/generator/index.vue | 2 +- src/views/monitor/log/index.vue | 4 +- src/views/monitor/online/index.vue | 2 +- src/views/open/app/index.vue | 2 +- src/views/schedule/job/index.vue | 2 +- src/views/schedule/log/index.vue | 2 +- src/views/system/client/index.vue | 2 +- src/views/system/config/index.vue | 4 +- src/views/system/dept/index.vue | 2 +- src/views/system/dict/index.vue | 6 +- src/views/system/file/main/FileAside.vue | 2 +- src/views/system/menu/index.vue | 2 +- src/views/system/notice/index.vue | 2 +- src/views/system/role/index.vue | 3 +- src/views/system/storage/index.vue | 2 +- src/views/system/user/index.vue | 6 +- 18 files changed, 123 insertions(+), 172 deletions(-) diff --git a/src/components/GiTable/index.vue b/src/components/GiTable/index.vue index 713592a1..a2ac9ea5 100644 --- a/src/components/GiTable/index.vue +++ b/src/components/GiTable/index.vue @@ -33,10 +33,10 @@ - + >