From 98d4e4d2e5011190919588e77c7df6c7af37216f Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Wed, 4 Feb 2026 15:18:50 +0800 Subject: [PATCH 1/6] =?UTF-8?q?fix:=E5=AF=BC=E5=87=BA=E8=B6=85=E6=97=B6?= =?UTF-8?q?=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/other.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/other.ts b/src/utils/other.ts index 7c0068e..e8ca3ab 100644 --- a/src/utils/other.ts +++ b/src/utils/other.ts @@ -300,6 +300,7 @@ export function postDownBlobFile(url: any, data: any, fileName: string) { descs: data?.descs ?? [], }, data, + timeout: 60 * 1000, }) .then((response) => { handleBlobFile(response, fileName) @@ -390,7 +391,7 @@ export function handleBlobFile(response: any, fileName: string) { } } if (typeof (blob as any).text === "function") { - (blob as any).text().then((t: string) => handleText(t)) + ;(blob as any).text().then((t: string) => handleText(t)) } else { const reader = new FileReader() reader.onload = () => handleText(String(reader.result || "")) From 989116052d67fa17223a39d94217667e90c3b706 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Wed, 4 Feb 2026 15:31:05 +0800 Subject: [PATCH 2/6] 111 --- src/utils/request.ts | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/utils/request.ts b/src/utils/request.ts index 1c38dd7..b66285f 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,8 +1,8 @@ import axios, {AxiosInstance, AxiosResponse, InternalAxiosRequestConfig} from 'axios'; -import { Session } from '/@/utils/storage'; -import { useMessageBox } from '/@/hooks/message'; -import qs from 'qs'; -import other from './other'; +import { Session } from "/@/utils/storage" +import { useMessageBox } from "/@/hooks/message" +import qs from "qs" +import other from "./other" /** * 创建并配置一个 Axios 实例对象 @@ -10,12 +10,12 @@ import other from './other'; const service: AxiosInstance = axios.create({ baseURL: import.meta.env.VITE_API_URL, timeout: 50000, // 全局超时时间 - paramsSerializer: { - serialize: (params: any) => { - return qs.stringify(params, {arrayFormat: 'repeat'}); - } - } -}); + paramsSerializer: { + serialize: (params: any) => { + return qs.stringify(params, { arrayFormat: "repeat" }) + }, + }, +}) /** * Axios请求拦截器,对请求进行处理 @@ -25,39 +25,38 @@ const service: AxiosInstance = axios.create({ * @param config AxiosRequestConfig对象,包含请求配置信息 */ service.interceptors.request.use( - (config: InternalAxiosRequestConfig) => { // 统一增加Authorization请求头, skipToken 跳过增加token - const token = Session.getToken(); + const token = Session.getToken() if (token && !config.headers?.skipToken) { - config.headers![CommonHeaderEnum.AUTHORIZATION] = `Bearer ${token}`; + config.headers![CommonHeaderEnum.AUTHORIZATION] = `Bearer ${token}` } // 统一增加TENANT-ID请求头 - const tenantId = Session.getTenant(); + const tenantId = Session.getTenant() if (tenantId) { - config.headers![CommonHeaderEnum.TENANT_ID] = tenantId; + config.headers![CommonHeaderEnum.TENANT_ID] = tenantId } // 请求报文加密 if (config.headers![CommonHeaderEnum.ENC_FLAG]) { - const enc = other.encryption(JSON.stringify(config.data), import.meta.env.VITE_PWD_ENC_KEY); + const enc = other.encryption(JSON.stringify(config.data), import.meta.env.VITE_PWD_ENC_KEY) config.data = { encryption: enc, - }; + } } // 自动适配单体和微服务架构不同的URL - config.url = other.adaptationUrl(config.url); + config.url = other.adaptationUrl(config.url) // 处理完毕,返回config对象 - return config; + return config }, (error) => { // 对请求错误进行处理 - return Promise.reject(error); - } -); + return Promise.reject(error) + }, +) /** * 响应拦截器处理函数 @@ -66,55 +65,56 @@ service.interceptors.request.use( */ const handleResponse = (response: AxiosResponse) => { if (response.data.code === 1) { - throw response.data; + throw response.data } // 针对密文返回解密 if (response.data.encryption) { - const originData = JSON.parse(other.decryption(response.data.encryption, import.meta.env.VITE_PWD_ENC_KEY)); - response.data = originData; - return response.data; + const originData = JSON.parse(other.decryption(response.data.encryption, import.meta.env.VITE_PWD_ENC_KEY)) + response.data = originData + return response.data } - return response.data; -}; + return response.data +} /** * 添加 Axios 的响应拦截器,用于全局响应结果处理 */ service.interceptors.response.use(handleResponse, (error) => { - const status = Number(error.response.status) || 200; + const status = Number(error.response.status) || 200 if (status === 423) { - return Promise.reject({msg:'"演示环境,仅供预览"'}); + return Promise.reject({ msg: '"演示环境,仅供预览"' }) } if (status === 424) { useMessageBox() - .confirm('令牌状态已过期,请点击重新登录') + .confirm("令牌状态已过期,请点击重新登录") .then(() => { - Session.clear(); // 清除浏览器全部临时缓存 - window.location.href = '/'; // 去登录页 - return; - }); + Session.clear() // 清除浏览器全部临时缓存 + window.location.href = "/" // 去登录页 + return + }) } if (status === 426) { useMessageBox() - .confirm('租户状态已过期,请联系管理员') + .confirm("租户状态已过期,请联系管理员") .then(() => { - Session.clear(); // 清除浏览器全部临时缓存 - return; - }); + Session.clear() // 清除浏览器全部临时缓存 + return + }) } - return Promise.reject(error.response.data); -}); + return Promise.reject(error.response.data) +}) // 常用header export enum CommonHeaderEnum { - 'TENANT_ID' = 'TENANT-ID', - 'ENC_FLAG' = 'Enc-Flag', - 'AUTHORIZATION' = 'Authorization', + "TENANT_ID" = "TENANT-ID", + "ENC_FLAG" = "Enc-Flag", + "AUTHORIZATION" = "Authorization", } // 导出 axios 实例 -export default service; +export default service + From 978877d86badcab0121a33665a79b01da6ded5d3 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Wed, 4 Feb 2026 16:29:21 +0800 Subject: [PATCH 3/6] 111 --- src/utils/other.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/other.ts b/src/utils/other.ts index e8ca3ab..f95ff58 100644 --- a/src/utils/other.ts +++ b/src/utils/other.ts @@ -300,7 +300,7 @@ export function postDownBlobFile(url: any, data: any, fileName: string) { descs: data?.descs ?? [], }, data, - timeout: 60 * 1000, + timeout: 360 * 1000, }) .then((response) => { handleBlobFile(response, fileName) From 3783e749342686b588adac06a9df5bfd4b437055 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Thu, 12 Mar 2026 16:07:01 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/app/app-menu.ts | 40 +++++++ src/api/login/index.ts | 147 +++++++++++++------------ src/views/biz/app/app-menu/form.vue | 146 +++++++++++++++++++++++++ src/views/biz/app/app-menu/index.vue | 154 +++++++++++++++++++++++++++ 4 files changed, 413 insertions(+), 74 deletions(-) create mode 100644 src/api/app/app-menu.ts create mode 100644 src/views/biz/app/app-menu/form.vue create mode 100644 src/views/biz/app/app-menu/index.vue diff --git a/src/api/app/app-menu.ts b/src/api/app/app-menu.ts new file mode 100644 index 0000000..67c8057 --- /dev/null +++ b/src/api/app/app-menu.ts @@ -0,0 +1,40 @@ +import request from "/@/utils/request" + +export function fetchList(query?: Object) { + return request({ + url: "/app/app-menu/page", + method: "get", + params: query, + }) +} + +export function addObj(obj?: Object) { + return request({ + url: "/app/app-menu", + method: "post", + data: obj, + }) +} + +export function getObj(id?: string) { + return request({ + url: "/app/app-menu/" + id, + method: "get", + }) +} + +export function delObjs(ids?: Object) { + return request({ + url: "/app/app-menu", + method: "delete", + data: ids, + }) +} + +export function putObj(obj?: Object) { + return request({ + url: "/app/app-menu", + method: "put", + data: obj, + }) +} diff --git a/src/api/login/index.ts b/src/api/login/index.ts index 828f1f4..f09033a 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -1,171 +1,170 @@ -import request from '/@/utils/request'; -import {Session} from '/@/utils/storage'; -import {validateNull} from '/@/utils/validate'; -import {useUserInfo} from '/@/stores/userInfo'; -import other from '/@/utils/other'; +import request from "/@/utils/request" +import { Session } from "/@/utils/storage" +import { validateNull } from "/@/utils/validate" +import { useUserInfo } from "/@/stores/userInfo" +import other from "/@/utils/other" /** * https://www.ietf.org/rfc/rfc6749.txt * OAuth 协议 4.3.1 要求格式为 form 而不是 JSON 注意! */ -const FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded'; +const FORM_CONTENT_TYPE = "application/x-www-form-urlencoded" // 登录方式 export enum LoginTypeEnum { PASSWORD, MOBILE, REGISTER, - EXPIRE + EXPIRE, } // 登录错误信息 export enum LoginErrorEnum { - CREDENTIALS_EXPIRED = 'credentials_expired'// 密码过期 + CREDENTIALS_EXPIRED = "credentials_expired", // 密码过期 } - /** * 登录 * @param data */ export const login = (data: any) => { - const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_PASSWORD_CLIENT); - Session.set('basicAuth', basicAuth); + const basicAuth = "Basic " + window.btoa(import.meta.env.VITE_OAUTH2_PASSWORD_CLIENT) + Session.set("basicAuth", basicAuth) // 密码加密 - const encPassword = other.encryption(data.password, import.meta.env.VITE_PWD_ENC_KEY); - const { username, randomStr, code, grant_type, scope } = data; + const encPassword = other.encryption(data.password, import.meta.env.VITE_PWD_ENC_KEY) + const { username, randomStr, code, grant_type, scope } = data return request({ - url: '/auth/oauth2/token', - method: 'post', + url: "/auth/oauth2/token", + method: "post", params: { username, randomStr, code, grant_type, scope }, data: { password: encPassword }, headers: { skipToken: true, Authorization: basicAuth, - 'Content-Type': FORM_CONTENT_TYPE, + "Content-Type": FORM_CONTENT_TYPE, }, - }); -}; + }) +} export const loginByMobile = (mobile: any, code: any) => { - const grant_type = 'mobile'; - const scope = 'server'; - const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_MOBILE_CLIENT); - Session.set('basicAuth', basicAuth); + const grant_type = "mobile" + const scope = "server" + const basicAuth = "Basic " + window.btoa(import.meta.env.VITE_OAUTH2_MOBILE_CLIENT) + Session.set("basicAuth", basicAuth) return request({ - url: '/auth/oauth2/token', + url: "/auth/oauth2/token", headers: { skipToken: true, Authorization: basicAuth, - 'Content-Type': FORM_CONTENT_TYPE, + "Content-Type": FORM_CONTENT_TYPE, }, - method: 'post', - params: { mobile: 'SMS@' + mobile, code: code, grant_type, scope }, - }); -}; + method: "post", + params: { mobile: "SMS@" + mobile, code: code, grant_type, scope }, + }) +} export const loginBySocial = (state: string, code: string) => { - const grant_type = 'mobile'; - const scope = 'server'; - const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_SOCIAL_CLIENT); - Session.set('basicAuth', basicAuth); + const grant_type = "mobile" + const scope = "server" + const basicAuth = "Basic " + window.btoa(import.meta.env.VITE_OAUTH2_SOCIAL_CLIENT) + Session.set("basicAuth", basicAuth) return request({ - url: '/auth/oauth2/token', + url: "/auth/oauth2/token", headers: { skipToken: true, Authorization: basicAuth, - 'Content-Type': FORM_CONTENT_TYPE, + "Content-Type": FORM_CONTENT_TYPE, }, - method: 'post', - params: { mobile: state + '@' + code, code: code, grant_type, scope }, - }); -}; + method: "post", + params: { mobile: state + "@" + code, code: code, grant_type, scope }, + }) +} export const sendMobileCode = (mobile: string) => { return request({ - url: '/admin/sysMessage/send/smsCode', - method: 'get', - params: { mobile } - }); -}; + url: "/admin/sysMessage/send/smsCode", + method: "get", + params: { mobile }, + }) +} export const refreshTokenApi = (refresh_token: string) => { - const grant_type = 'refresh_token'; - const scope = 'server'; + const grant_type = "refresh_token" + const scope = "server" // 获取当前选中的 basic 认证信息 - const basicAuth = Session.get('basicAuth'); + const basicAuth = Session.get("basicAuth") return request({ - url: '/auth/oauth2/token', + url: "/auth/oauth2/token", headers: { skipToken: true, Authorization: basicAuth, - 'Content-Type': FORM_CONTENT_TYPE, + "Content-Type": FORM_CONTENT_TYPE, }, - method: 'post', + method: "post", params: { refresh_token, grant_type, scope }, - }); -}; + }) +} /** * 校验令牌,若有效期小于半小时自动续期 * @param refreshLock */ export const checkToken = (refreshTime: number, refreshLock: boolean) => { - const basicAuth = Session.get('basicAuth'); + const basicAuth = Session.get("basicAuth") request({ - url: '/auth/token/check_token', + url: "/auth/token/check_token", headers: { skipToken: true, Authorization: basicAuth, - 'Content-Type': FORM_CONTENT_TYPE, + "Content-Type": FORM_CONTENT_TYPE, }, - method: 'get', + method: "get", params: { token: Session.getToken() }, }) .then((response) => { if (validateNull(response) || response.code === 1) { - clearInterval(refreshTime); - return; + clearInterval(refreshTime) + return } - const expire = Date.parse(response.data.expiresAt); + const expire = Date.parse(response.data.expiresAt) if (expire) { - const expiredPeriod = expire - new Date().getTime(); + const expiredPeriod = expire - new Date().getTime() //小于半小时自动续约 if (expiredPeriod <= 30 * 60 * 1000) { if (!refreshLock) { - refreshLock = true; + refreshLock = true useUserInfo() .refreshToken() .catch(() => { - clearInterval(refreshTime); - }); - refreshLock = false; + clearInterval(refreshTime) + }) + refreshLock = false } } } }) .catch(() => { // 发生异常关闭定时器 - clearInterval(refreshTime); - }); -}; + clearInterval(refreshTime) + }) +} /** * 获取用户信息 */ export const getUserInfo = () => { return request({ - url: '/admin/user/info', - method: 'get', - }); -}; + url: "/admin/user/info", + method: "get", + }) +} export const logout = () => { return request({ - url: '/auth/token/logout', - method: 'delete', - }); -}; + url: "/auth/token/logout", + method: "delete", + }) +} diff --git a/src/views/biz/app/app-menu/form.vue b/src/views/biz/app/app-menu/form.vue new file mode 100644 index 0000000..4936a73 --- /dev/null +++ b/src/views/biz/app/app-menu/form.vue @@ -0,0 +1,146 @@ + + + \ No newline at end of file diff --git a/src/views/biz/app/app-menu/index.vue b/src/views/biz/app/app-menu/index.vue new file mode 100644 index 0000000..d697d71 --- /dev/null +++ b/src/views/biz/app/app-menu/index.vue @@ -0,0 +1,154 @@ + + + \ No newline at end of file From f1e9c596b52914d69e4a04b31a48fb8af81ebe1a Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Sat, 14 Mar 2026 18:46:16 +0800 Subject: [PATCH 5/6] 11 --- src/views/biz/app/app-menu/index.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/views/biz/app/app-menu/index.vue b/src/views/biz/app/app-menu/index.vue index d697d71..574856e 100644 --- a/src/views/biz/app/app-menu/index.vue +++ b/src/views/biz/app/app-menu/index.vue @@ -54,8 +54,12 @@ - - + + + +