From 2e58e58c7394dad80f00b9ef6f768b8bdf662e76 Mon Sep 17 00:00:00 2001 From: guanj Date: Tue, 23 Sep 2025 08:44:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/request.ts | 611 +++---- .../currentDevice.vue | 554 +++--- src/views/govern/device/fileService/index.vue | 1573 +++++++++-------- src/views/govern/mxgraph/graphList/index.vue | 516 +++--- 4 files changed, 1660 insertions(+), 1594 deletions(-) diff --git a/src/utils/request.ts b/src/utils/request.ts index ca7851a..c13181f 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,298 +1,313 @@ -import type { AxiosRequestConfig, Method } from 'axios' -import axios from 'axios' -import { ElLoading, ElMessage, ElNotification, type LoadingOptions } from 'element-plus' -import { refreshToken } from '@/api/user-boot/user' -import router from '@/router/index' -import { useAdminInfo } from '@/stores/adminInfo' -import { set } from 'lodash' - -window.requests = [] -window.tokenRefreshing = false -const pendingMap = new Map() -const loadingInstance: LoadingInstance = { - target: null, - count: 0 -} - -/** - * 根据运行环境获取基础请求URL - */ -export const getUrl = (): string => { - return '/api' -} - -/** - * 创建`Axios` - * 默认开启`reductDataFormat(简洁响应)`,返回类型为`ApiPromise` - * 关闭`reductDataFormat`,返回类型则为`AxiosPromise` - */ -function createAxios>( - axiosConfig: AxiosRequestConfig, - options: Options = {}, - loading: LoadingOptions = {} -): T { - const adminInfo = useAdminInfo() - - const Axios = axios.create({ - baseURL: getUrl(), - timeout: 1000 * 60 * 5, - headers: {}, - responseType: 'json' - }) - - options = Object.assign( - { - CancelDuplicateRequest: true, // 是否开启取消重复请求, 默认为 true - loading: false, // 是否开启loading层效果, 默认为false - reductDataFormat: true, // 是否开启简洁的数据结构响应, 默认为true - showErrorMessage: true, // 是否开启接口错误信息展示,默认为true - showCodeMessage: true, // 是否开启code不为1时的信息提示, 默认为true - showSuccessMessage: false, // 是否开启code为1时的信息提示, 默认为false - anotherToken: '' // 当前请求使用另外的用户token - }, - options - ) - - // 请求拦截 - Axios.interceptors.request.use( - config => { - // if(config.url?.substring(0, 13)=='/advance-boot'){ - // config.url=config.url?.slice(13) - // config.baseURL='/hzj' - // } - // 取消重复请求 - - if ( - !( - config.url == '/system-boot/file/upload' || - config.url == '/harmonic-boot/grid/getAssessOverview' || - config.url == '/harmonic-boot/gridDiagram/getGridDiagramAreaData' - ) - ) - removePending(config) - - options.CancelDuplicateRequest && addPending(config) - // 创建loading实例 - if (options.loading) { - loadingInstance.count++ - if (loadingInstance.count === 1) { - loadingInstance.target = ElLoading.service(loading) - } - } - // 自动携带token - if (config.headers) { - const token = adminInfo.getToken() - if (token) { - ;(config.headers as anyObj).Authorization = token - } else { - config.headers.Authorization = 'Basic bmpjbnRlc3Q6bmpjbnBxcw==' - } - } - if (config.url == '/user-boot/user/generateSm2Key' || config.url == '/pqs-auth/oauth/token') { - config.headers.Authorization = 'Basic bmpjbnRlc3Q6bmpjbnBxcw==' - } - - return config - }, - error => { - return Promise.reject(error) - } - ) - - // 响应拦截 - Axios.interceptors.response.use( - response => { - removePending(response.config) - options.loading && closeLoading(options) // 关闭loading - if ( - response.data.code === 'A0000' || - response.data.type === 'application/json' || - Array.isArray(response.data) || - response.data.size - // || - // response.data.type === 'application/octet-stream' || - // response.data.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ) { - return options.reductDataFormat ? response.data : response - } else if (response.data.code == 'A0202') { - if (!window.tokenRefreshing) { - window.tokenRefreshing = true - return refreshToken() - .then(res => { - adminInfo.setToken(res.data.access_token, 'auth') - window.requests.forEach(cb => cb(res.data.access_token)) - window.requests = [] - - return Axios(response.config) - }) - .catch(err => { - adminInfo.removeToken() - router.push({ name: 'login' }) - return Promise.reject(err) - }) - .finally(() => { - window.tokenRefreshing = false - }) - } else { - return new Promise(resolve => { - // 用函数形式将 resolve 存入,等待刷新后再执行 - window.requests.push((token: string) => { - response.headers.Authorization = `${token}` - resolve(Axios(response.config)) - }) - }) - } - } else if (response.data.code == 'A0024') { - // 登录失效 - ElMessage({ - type: 'error', - message: response.data.message - }) - adminInfo.removeToken() - router.push({ name: 'login' }) - return Promise.reject(response.data) - } else { - if (options.showCodeMessage) { - if (response.config.url == '/access-boot/device/wlRegister') { - setTimeout(() => { - ElMessage.error(response.data.message || '未知错误') - }, 6000) - } else { - ElMessage.error(response.data.message || '未知错误') - } - } - return Promise.reject(response.data) - } - }, - error => { - error.config && removePending(error.config) - options.loading && closeLoading(options) // 关闭loading - return Promise.reject(error) // 错误继续返回给到具体页面 - } - ) - return Axios(axiosConfig) as T -} - -export default createAxios - -/** - * 关闭Loading层实例 - */ -function closeLoading(options: Options) { - if (options.loading && loadingInstance.count > 0) loadingInstance.count-- - if (loadingInstance.count === 0) { - loadingInstance.target.close() - loadingInstance.target = null - } -} - -/** - * 储存每个请求的唯一cancel回调, 以此为标识 - */ -function addPending(config: AxiosRequestConfig) { - const pendingKey = getPendingKey(config) - config.cancelToken = - config.cancelToken || - new axios.CancelToken(cancel => { - if (!pendingMap.has(pendingKey)) { - pendingMap.set(pendingKey, cancel) - } - }) -} - -/** - * 删除重复的请求 - */ -function removePending(config: AxiosRequestConfig) { - const pendingKey = getPendingKey(config) - if (pendingMap.has(pendingKey)) { - const cancelToken = pendingMap.get(pendingKey) - cancelToken(pendingKey) - pendingMap.delete(pendingKey) - } -} - -/** - * 生成每个请求的唯一key - */ -function getPendingKey(config: AxiosRequestConfig) { - let { data } = config - const { url, method, params, headers } = config - if (typeof data === 'string') data = JSON.parse(data) // response里面返回的config.data是个字符串对象 - return [ - url, - method, - headers && (headers as anyObj).Authorization ? (headers as anyObj).Authorization : '', - headers && (headers as anyObj)['ba-user-token'] ? (headers as anyObj)['ba-user-token'] : '', - JSON.stringify(params), - JSON.stringify(data) - ].join('&') -} - -/** - * 根据请求方法组装请求数据/参数 - */ -export function requestPayload(method: Method, data: anyObj, paramsPOST: boolean) { - if (method == 'GET') { - return { - params: data - } - } else if (method == 'POST') { - if (paramsPOST) { - return { params: data } - } else { - return { data: data } - } - } -} -// 适配器, 用于适配不同的请求方式 -export function baseRequest(url, value = {}, method = 'post', options = {}) { - url = sysConfig?.API_URL + url - if (method === 'post') { - return service.post(url, value, options) - } else if (method === 'get') { - return service.get(url, { params: value, ...options }) - } else if (method === 'formdata') { - // form-data表单提交的方式 - return service.post(url, qs.stringify(value), { - headers: { - 'Content-Type': 'multipart/form-data' - }, - ...options - }) - } else { - // 其他请求方式,例如:put、delete - return service({ - method: method, - url: url, - data: value, - ...options - }) - } -} -// 模块内的请求, 会自动加上模块的前缀 -export const moduleRequest = - moduleUrl => - (url, ...arg) => { - return baseRequest(moduleUrl + url, ...arg) - } - -interface LoadingInstance { - target: any - count: number -} - -interface Options { - // 是否开启取消重复请求, 默认为 true - CancelDuplicateRequest?: boolean - // 是否开启loading层效果, 默认为false - loading?: boolean - // 是否开启简洁的数据结构响应, 默认为true - reductDataFormat?: boolean - // 是否开启code不为A0000时的信息提示, 默认为true - showCodeMessage?: boolean - // 是否开启code为0时的信息提示, 默认为false - showSuccessMessage?: boolean - // 当前请求使用另外的用户token - anotherToken?: string -} +import type { AxiosRequestConfig, Method } from 'axios' +import axios from 'axios' +import { ElLoading, ElMessage, ElNotification, type LoadingOptions } from 'element-plus' +import { refreshToken } from '@/api/user-boot/user' +import router from '@/router/index' +import { useAdminInfo } from '@/stores/adminInfo' + +window.requests = [] +window.tokenRefreshing = false +let loginExpireTimer:any=null +const pendingMap = new Map() +const loadingInstance: LoadingInstance = { + target: null, + count: 0 +} + +/** + * 根据运行环境获取基础请求URL + */ +export const getUrl = (): string => { + return '/api' +} + +/** + * 创建`Axios` + * 默认开启`reductDataFormat(简洁响应)`,返回类型为`ApiPromise` + * 关闭`reductDataFormat`,返回类型则为`AxiosPromise` + */ +function createAxios>( + axiosConfig: AxiosRequestConfig, + options: Options = {}, + loading: LoadingOptions = {} +): T { + const adminInfo = useAdminInfo() + + const Axios = axios.create({ + baseURL: getUrl(), + timeout: 1000 * 60 * 5, + headers: {}, + responseType: 'json' + }) + + options = Object.assign( + { + CancelDuplicateRequest: true, // 是否开启取消重复请求, 默认为 true + loading: false, // 是否开启loading层效果, 默认为false + reductDataFormat: true, // 是否开启简洁的数据结构响应, 默认为true + showErrorMessage: true, // 是否开启接口错误信息展示,默认为true + showCodeMessage: true, // 是否开启code不为1时的信息提示, 默认为true + showSuccessMessage: false, // 是否开启code为1时的信息提示, 默认为false + anotherToken: '' // 当前请求使用另外的用户token + }, + options + ) + + // 请求拦截 + Axios.interceptors.request.use( + config => { + // if(config.url?.substring(0, 13)=='/advance-boot'){ + // config.url=config.url?.slice(13) + // config.baseURL='/hzj' + // } + // 取消重复请求 + + if ( + !( + config.url == '/system-boot/file/upload' || + config.url == '/harmonic-boot/grid/getAssessOverview' || + config.url == '/harmonic-boot/gridDiagram/getGridDiagramAreaData' + ) + ) + removePending(config) + + options.CancelDuplicateRequest && addPending(config) + // 创建loading实例 + if (options.loading) { + loadingInstance.count++ + if (loadingInstance.count === 1) { + loadingInstance.target = ElLoading.service(loading) + } + } + // 自动携带token + if (config.headers) { + const token = adminInfo.getToken() + if (token) { + ;(config.headers as anyObj).Authorization = token + } else { + config.headers.Authorization = 'Basic bmpjbnRlc3Q6bmpjbnBxcw==' + } + } + if (config.url == '/user-boot/user/generateSm2Key' || config.url == '/pqs-auth/oauth/token') { + config.headers.Authorization = 'Basic bmpjbnRlc3Q6bmpjbnBxcw==' + } + + return config + }, + error => { + return Promise.reject(error) + } + ) + + // 响应拦截 + Axios.interceptors.response.use( + response => { + removePending(response.config) + options.loading && closeLoading(options) // 关闭loading + if ( + response.data.code === 'A0000' || + response.data.type === 'application/json' || + Array.isArray(response.data) || + response.data.size + // || + // response.data.type === 'application/octet-stream' || + // response.data.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + ) { + return options.reductDataFormat ? response.data : response + } else if (response.data.code == 'A0202') { + if (!window.tokenRefreshing) { + window.tokenRefreshing = true + return refreshToken() + .then(res => { + adminInfo.setToken(res.data.access_token, 'auth') + window.requests.forEach(cb => cb(res.data.access_token)) + window.requests = [] + + return Axios(response.config) + }) + .catch(err => { + adminInfo.removeToken() + router.push({ name: 'login' }) + return Promise.reject(err) + }) + .finally(() => { + window.tokenRefreshing = false + }) + } else { + return new Promise(resolve => { + // 用函数形式将 resolve 存入,等待刷新后再执行 + window.requests.push((token: string) => { + response.headers.Authorization = `${token}` + resolve(Axios(response.config)) + }) + }) + } + } else if (response.data.code == 'A0024') { + // // 登录失效 + // 清除上一次的定时器 + if (loginExpireTimer) { + clearTimeout(loginExpireTimer) + } + loginExpireTimer = setTimeout(() => { + ElNotification({ + type: 'error', + message: response.data.message + }) + adminInfo.removeToken() + router.push({ name: 'login' }) + loginExpireTimer = null // 执行后清空定时器 + }, 100) // 可根据实际情况调整延迟时间 + return Promise.reject(response.data) + // // 登录失效 + // ElMessage({ + // type: 'error', + // message: response.data.message + // }) + // adminInfo.removeToken() + // router.push({ name: 'login' }) + // return Promise.reject(response.data) + } else { + if (options.showCodeMessage) { + if (response.config.url == '/access-boot/device/wlRegister') { + setTimeout(() => { + ElMessage.error(response.data.message || '未知错误') + }, 6000) + } else { + ElMessage.error(response.data.message || '未知错误') + } + } + return Promise.reject(response.data) + } + }, + error => { + error.config && removePending(error.config) + options.loading && closeLoading(options) // 关闭loading + return Promise.reject(error) // 错误继续返回给到具体页面 + } + ) + return Axios(axiosConfig) as T +} + +export default createAxios + +/** + * 关闭Loading层实例 + */ +function closeLoading(options: Options) { + if (options.loading && loadingInstance.count > 0) loadingInstance.count-- + if (loadingInstance.count === 0) { + loadingInstance.target.close() + loadingInstance.target = null + } +} + +/** + * 储存每个请求的唯一cancel回调, 以此为标识 + */ +function addPending(config: AxiosRequestConfig) { + const pendingKey = getPendingKey(config) + config.cancelToken = + config.cancelToken || + new axios.CancelToken(cancel => { + if (!pendingMap.has(pendingKey)) { + pendingMap.set(pendingKey, cancel) + } + }) +} + +/** + * 删除重复的请求 + */ +function removePending(config: AxiosRequestConfig) { + const pendingKey = getPendingKey(config) + if (pendingMap.has(pendingKey)) { + const cancelToken = pendingMap.get(pendingKey) + cancelToken(pendingKey) + pendingMap.delete(pendingKey) + } +} + +/** + * 生成每个请求的唯一key + */ +function getPendingKey(config: AxiosRequestConfig) { + let { data } = config + const { url, method, params, headers } = config + if (typeof data === 'string') data = JSON.parse(data) // response里面返回的config.data是个字符串对象 + return [ + url, + method, + headers && (headers as anyObj).Authorization ? (headers as anyObj).Authorization : '', + headers && (headers as anyObj)['ba-user-token'] ? (headers as anyObj)['ba-user-token'] : '', + JSON.stringify(params), + JSON.stringify(data) + ].join('&') +} + +/** + * 根据请求方法组装请求数据/参数 + */ +export function requestPayload(method: Method, data: anyObj, paramsPOST: boolean) { + if (method == 'GET') { + return { + params: data + } + } else if (method == 'POST') { + if (paramsPOST) { + return { params: data } + } else { + return { data: data } + } + } +} +// 适配器, 用于适配不同的请求方式 +export function baseRequest(url, value = {}, method = 'post', options = {}) { + url = sysConfig?.API_URL + url + if (method === 'post') { + return service.post(url, value, options) + } else if (method === 'get') { + return service.get(url, { params: value, ...options }) + } else if (method === 'formdata') { + // form-data表单提交的方式 + return service.post(url, qs.stringify(value), { + headers: { + 'Content-Type': 'multipart/form-data' + }, + ...options + }) + } else { + // 其他请求方式,例如:put、delete + return service({ + method: method, + url: url, + data: value, + ...options + }) + } +} +// 模块内的请求, 会自动加上模块的前缀 +export const moduleRequest = + moduleUrl => + (url, ...arg) => { + return baseRequest(moduleUrl + url, ...arg) + } + +interface LoadingInstance { + target: any + count: number +} + +interface Options { + // 是否开启取消重复请求, 默认为 true + CancelDuplicateRequest?: boolean + // 是否开启loading层效果, 默认为false + loading?: boolean + // 是否开启简洁的数据结构响应, 默认为true + reductDataFormat?: boolean + // 是否开启code不为A0000时的信息提示, 默认为true + showCodeMessage?: boolean + // 是否开启code为0时的信息提示, 默认为false + showSuccessMessage?: boolean + // 当前请求使用另外的用户token + anotherToken?: string +} diff --git a/src/views/govern/device/control/supplementaryRecruitment/currentDevice.vue b/src/views/govern/device/control/supplementaryRecruitment/currentDevice.vue index 4bdfbdd..b20297f 100644 --- a/src/views/govern/device/control/supplementaryRecruitment/currentDevice.vue +++ b/src/views/govern/device/control/supplementaryRecruitment/currentDevice.vue @@ -1,273 +1,281 @@ - - - + + + diff --git a/src/views/govern/device/fileService/index.vue b/src/views/govern/device/fileService/index.vue index 8e35fb9..1d7ea0f 100644 --- a/src/views/govern/device/fileService/index.vue +++ b/src/views/govern/device/fileService/index.vue @@ -1,761 +1,812 @@ - - - - - - - + + + + + + + diff --git a/src/views/govern/mxgraph/graphList/index.vue b/src/views/govern/mxgraph/graphList/index.vue index 4ee3bc8..10bdb64 100644 --- a/src/views/govern/mxgraph/graphList/index.vue +++ b/src/views/govern/mxgraph/graphList/index.vue @@ -1,262 +1,254 @@ - - - + + +