.env.test | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/Editor/src/Editor.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/UploadFile/src/useUpload.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/config/axios/service.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/router/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
types/env.d.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
.env.test
@@ -8,8 +8,6 @@ # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务 VITE_UPLOAD_TYPE=server # 上传路径 VITE_UPLOAD_URL='http://172.16.8.100/admin-api/infra/file/upload' # 接口地址 VITE_API_URL=/admin-api src/components/Editor/src/Editor.vue
@@ -7,6 +7,7 @@ import { ElMessage } from 'element-plus' import { useLocaleStore } from '@/store/modules/locale' import { getAccessToken, getTenantId } from '@/utils/auth' import { getUploadUrl } from '@/components/UploadFile/src/useUpload' defineOptions({ name: 'Editor' }) @@ -88,7 +89,7 @@ scroll: true, MENU_CONF: { ['uploadImage']: { server: import.meta.env.VITE_UPLOAD_URL, server: getUploadUrl(), // 单个文件的最大体积限制,默认为 2M maxFileSize: 5 * 1024 * 1024, // 最多可上传几个文件,默认为 100 @@ -136,7 +137,7 @@ } }, ['uploadVideo']: { server: import.meta.env.VITE_UPLOAD_URL, server: getUploadUrl(), // 单个文件的最大体积限制,默认为 10M maxFileSize: 10 * 1024 * 1024, // 最多可上传几个文件,默认为 100 src/components/UploadFile/src/useUpload.ts
@@ -3,9 +3,16 @@ import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload' import axios from 'axios' /** * 获得上传 URL */ export const getUploadUrl = (): string => { return import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload' } export const useUpload = () => { // 后端上传地址 const uploadUrl = import.meta.env.VITE_UPLOAD_URL const uploadUrl = getUploadUrl() // 是否使用前端直连上传 const isClientUpload = UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE // 重写ElUpload上传方法 @@ -17,16 +24,18 @@ // 1.2 获取文件预签名地址 const presignedInfo = await FileApi.getFilePresignedUrl(fileName) // 1.3 上传文件(不能使用 ElUpload 的 ajaxUpload 方法的原因:其使用的是 FormData 上传,Minio 不支持) return axios.put(presignedInfo.uploadUrl, options.file, { headers: { 'Content-Type': options.file.type, } }).then(() => { // 1.4. 记录文件信息到后端(异步) createFile(presignedInfo, fileName, options.file) // 通知成功,数据格式保持与后端上传的返回结果一致 return { data: presignedInfo.url } }) return axios .put(presignedInfo.uploadUrl, options.file, { headers: { 'Content-Type': options.file.type } }) .then(() => { // 1.4. 记录文件信息到后端(异步) createFile(presignedInfo, fileName, options.file) // 通知成功,数据格式保持与后端上传的返回结果一致 return { data: presignedInfo.url } }) } else { // 模式二:后端上传 // 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子 src/config/axios/service.ts
@@ -1,10 +1,4 @@ import axios, { AxiosError, AxiosInstance, AxiosRequestHeaders, AxiosResponse, InternalAxiosRequestConfig } from 'axios' import axios, { AxiosError, AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios' import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' import qs from 'qs' @@ -37,7 +31,11 @@ const service: AxiosInstance = axios.create({ baseURL: base_url, // api 的 base_url timeout: request_timeout, // 请求超时时间 withCredentials: false // 禁用 Cookie 等信息 withCredentials: false, // 禁用 Cookie 等信息 // 自定义参数序列化函数 paramsSerializer: (params) => { return qs.stringify(params, { allowDots: true }) } }) // request拦截器 @@ -46,34 +44,31 @@ // 是否需要设置 token let isToken = (config!.headers || {}).isToken === false whiteList.some((v) => { if (config.url) { config.url.indexOf(v) > -1 if (config.url && config.url.indexOf(v) > -1) { return (isToken = false) } }) if (getAccessToken() && !isToken) { ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token config.headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token } // 设置租户 if (tenantEnable && tenantEnable === 'true') { const tenantId = getTenantId() if (tenantId) (config as Recordable).headers['tenant-id'] = tenantId if (tenantId) config.headers['tenant-id'] = tenantId } const params = config.params || {} const data = config.data || false if ( config.method?.toUpperCase() === 'POST' && (config.headers as AxiosRequestHeaders)['Content-Type'] === 'application/x-www-form-urlencoded' ) { config.data = qs.stringify(data) const method = config.method?.toUpperCase() // 防止 GET 请求缓存 if (method === 'GET') { config.headers['Cache-Control'] = 'no-cache' config.headers['Pragma'] = 'no-cache' } // get参数编码 if (config.method?.toUpperCase() === 'GET' && params) { config.params = {} const paramsStr = qs.stringify(params, { allowDots: true }) if (paramsStr) { config.url = config.url + '?' + paramsStr // 自定义参数序列化函数 else if (method === 'POST') { const contentType = config.headers['Content-Type'] || config.headers['content-type'] if (contentType === 'application/x-www-form-urlencoded') { if (config.data && typeof config.data !== 'string') { config.data = qs.stringify(config.data) } } } return config @@ -165,7 +160,7 @@ t('sys.api.errMsg901') + '</div>' + '<div> </div>' + '<div>参考 https://xxxx/ 教程</div>' + '<div>参考 https://doc.iailab.cn/ 教程</div>' + '<div> </div>' + '<div>5 分钟搭建本地环境</div>' }) @@ -206,15 +201,12 @@ const handleAuthorized = () => { const { t } = useI18n() if (!isRelogin.show) { // 如果已经到重新登录页面则不进行弹窗提示 if (window.location.href.includes('login?redirect=')) { return } isRelogin.show = true ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), { showCancelButton: false, closeOnClickModal: false, showClose: false, closeOnPressEscape: false, confirmButtonText: t('login.relogin'), type: 'warning' }).then(() => { src/router/index.ts
@@ -5,7 +5,7 @@ // 创建路由实例 const router = createRouter({ history: createWebHistory('/plat'), // createWebHashHistory URL带#,createWebHistory URL不带# history: createWebHistory(import.meta.env.VITE_BASE_PATH), // createWebHashHistory URL带#,createWebHistory URL不带# strict: true, routes: remainingRouter as RouteRecordRaw[], scrollBehavior: () => ({ left: 0, top: 0 }) types/env.d.ts
@@ -22,9 +22,9 @@ readonly VITE_APP_DEFAULT_LOGIN_PASSWORD: string readonly VITE_APP_DOCALERT_ENABLE: string readonly VITE_BASE_URL: string readonly VITE_UPLOAD_URL: string readonly VITE_API_URL: string readonly VITE_BASE_PATH: string readonly VITE_UPLOAD_TYPE: string readonly VITE_VIDEO_CAMERA_DOMAIN: string readonly VITE_DROP_DEBUGGER: string readonly VITE_DROP_CONSOLE: string