diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java index b732a0cba..2f384bf20 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java @@ -1,7 +1,6 @@ package com.ruoyi.web.controller.system; import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -80,7 +79,6 @@ public class SysConfigController extends BaseController { @PreAuthorize("@ss.hasPermi('system:config:add')") @Log(title = "参数管理", businessType = BusinessType.INSERT) @PostMapping - @RepeatSubmit public AjaxResult add(@Validated @RequestBody SysConfig config) { if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) { return AjaxResult.error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index 7e28c2e9e..765017054 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -108,7 +108,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']" >导出 @@ -324,8 +323,6 @@ export default { buttonLoading: false, // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], #if($table.sub) @@ -573,7 +570,9 @@ export default { #end /** 导出按钮操作 */ handleExport() { - this.#[[$download]]#.excel('/${moduleName}/${businessName}/export', this.queryParams); + this.download('${moduleName}/${businessName}/export', { + ...this.queryParams + }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`) } } }; diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 89d591b34..acb1fcb2b 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -37,9 +37,9 @@ }, "dependencies": { "@riophae/vue-treeselect": "0.4.0", - "axios": "0.21.0", + "axios": "0.24.0", "clipboard": "2.0.6", - "core-js": "3.8.1", + "core-js": "3.19.1", "echarts": "4.9.0", "element-ui": "2.15.6", "file-saver": "2.0.5", diff --git a/ruoyi-ui/src/api/monitor/job.js b/ruoyi-ui/src/api/monitor/job.js index 58c43434a..38155693a 100644 --- a/ruoyi-ui/src/api/monitor/job.js +++ b/ruoyi-ui/src/api/monitor/job.js @@ -43,15 +43,6 @@ export function delJob(jobId) { }) } -// 导出定时任务调度 -export function exportJob(query) { - return request({ - url: '/monitor/job/export', - method: 'get', - params: query - }) -} - // 任务状态修改 export function changeJobStatus(jobId, status) { const data = { diff --git a/ruoyi-ui/src/api/system/post.js b/ruoyi-ui/src/api/system/post.js index 434cd3513..1a8e9ca04 100644 --- a/ruoyi-ui/src/api/system/post.js +++ b/ruoyi-ui/src/api/system/post.js @@ -42,12 +42,3 @@ export function delPost(postId) { method: 'delete' }) } - -// 导出岗位 -export function exportPost(query) { - return request({ - url: '/system/post/export', - method: 'get', - params: query - }) -} \ No newline at end of file diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js index c6306a65c..76e33d59e 100644 --- a/ruoyi-ui/src/main.js +++ b/ruoyi-ui/src/main.js @@ -12,6 +12,7 @@ import store from './store' import router from './router' import directive from './directive' //directive import plugins from './plugins' // plugins +import { download } from '@/utils/request' import './assets/icons' // icon import './permission' // permission control @@ -43,6 +44,7 @@ Vue.prototype.resetForm = resetForm Vue.prototype.addDateRange = addDateRange Vue.prototype.selectDictLabel = selectDictLabel Vue.prototype.selectDictLabels = selectDictLabels +Vue.prototype.download = download Vue.prototype.handleTree = handleTree // 全局组件挂载 diff --git a/ruoyi-ui/src/plugins/download.js b/ruoyi-ui/src/plugins/download.js index ec7bdd497..94249eec9 100644 --- a/ruoyi-ui/src/plugins/download.js +++ b/ruoyi-ui/src/plugins/download.js @@ -1,7 +1,8 @@ -import { saveAs } from 'file-saver' import axios from 'axios' -import { getToken } from '@/utils/auth' import { Message } from 'element-ui' +import { saveAs } from 'file-saver' +import { getToken } from '@/utils/auth' +import { blobValidate } from "@/utils/ruoyi"; const baseURL = process.env.VUE_APP_BASE_API @@ -71,7 +72,7 @@ export default { responseType: 'blob', headers: { 'Authorization': 'Bearer ' + getToken() } }).then(async (res) => { - const isLogin = await this.blobValidate(res.data); + const isLogin = await blobValidate(res.data); if (isLogin) { const blob = new Blob([res.data], { type: 'application/zip' }) this.saveAs(blob, name) @@ -82,15 +83,6 @@ export default { }, saveAs(text, name, opts) { saveAs(text, name, opts); - }, - async blobValidate(data) { - try { - const text = await data.text(); - JSON.parse(text); - return false; - } catch (error) { - return true; - } - }, + } } diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js index 31944e2a2..deff980bf 100644 --- a/ruoyi-ui/src/utils/request.js +++ b/ruoyi-ui/src/utils/request.js @@ -1,8 +1,12 @@ import axios from 'axios' -import { Notification, MessageBox, Message } from 'element-ui' +import { Notification, MessageBox, Message, Loading } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' import errorCode from '@/utils/errorCode' +import { tansParams, blobValidate } from "@/utils/ruoyi"; +import { saveAs } from 'file-saver' + +let downloadLoadingInstance; axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' // 对应国际化资源文件后缀 @@ -14,6 +18,7 @@ const service = axios.create({ // 超时 timeout: 10000 }) + // request拦截器 service.interceptors.request.use(config => { // 是否需要设置 token @@ -23,24 +28,7 @@ service.interceptors.request.use(config => { } // get请求映射params参数 if (config.method === 'get' && config.params) { - let url = config.url + '?'; - for (const propName of Object.keys(config.params)) { - const value = config.params[propName]; - var part = encodeURIComponent(propName) + "="; - if (value !== null && typeof(value) !== "undefined") { - if (typeof value === 'object') { - for (const key of Object.keys(value)) { - if (value[key] !== null && typeof (value[key]) !== 'undefined') { - let params = propName + '[' + key + ']'; - let subPart = encodeURIComponent(params) + '='; - url += subPart + encodeURIComponent(value[key]) + '&'; - } - } - } else { - url += part + encodeURIComponent(value) + "&"; - } - } - } + let url = config.url + '?' + tansParams(config.params); url = url.slice(0, -1); config.params = {}; config.url = url; @@ -57,17 +45,24 @@ service.interceptors.response.use(res => { const code = res.data.code || 200; // 获取错误信息 const msg = errorCode[code] || res.data.msg || errorCode['default'] + // 二进制数据则直接返回 + if(res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer'){ + return res.data + } if (code === 401) { - MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { + let doms = document.getElementsByClassName('el-message-box')[0] + if(doms === undefined){ + MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' } - ).then(() => { - store.dispatch('LogOut').then(() => { - location.href = process.env.VUE_APP_CONTEXT_PATH + "index"; - }) - }).catch(() => {}); + ).then(() => { + store.dispatch('LogOut').then(() => { + location.href = process.env.VUE_APP_CONTEXT_PATH + "index"; + }) + }).catch(() => {}); + } return Promise.reject('无效的会话,或者会话已过期,请重新登录。') } else if (code === 500) { Message({ @@ -105,4 +100,27 @@ service.interceptors.response.use(res => { } ) +// 通用下载方法 +export function download(url, params, filename) { + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) + return service.post(url, params, { + transformRequest: [(params) => { return tansParams(params) }], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob' + }).then(async (data) => { + const isLogin = await blobValidate(data); + if (isLogin) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + Message.error('无效的会话,或者会话已过期,请重新登录。'); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) +} + export default service diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js index 440bf4cd8..4cc5e24ea 100644 --- a/ruoyi-ui/src/utils/ruoyi.js +++ b/ruoyi-ui/src/utils/ruoyi.js @@ -181,3 +181,40 @@ export function handleTree(data, id, parentId, children) { } return tree; } + +/** +* 参数处理 +* @param {*} params 参数 +*/ +export function tansParams(params) { + let result = '' + for (const propName of Object.keys(params)) { + const value = params[propName]; + var part = encodeURIComponent(propName) + "="; + if (value !== null && typeof (value) !== "undefined") { + if (typeof value === 'object') { + for (const key of Object.keys(value)) { + if (value[key] !== null && typeof (value[key]) !== 'undefined') { + let params = propName + '[' + key + ']'; + var subPart = encodeURIComponent(params) + "="; + result += subPart + encodeURIComponent(value[key]) + "&"; + } + } + } else { + result += part + encodeURIComponent(value) + "&"; + } + } + } + return result +} + +// 验证是否为blob格式 +export async function blobValidate(data) { + try { + const text = await data.text(); + JSON.parse(text); + return false; + } catch (error) { + return true; + } +} diff --git a/ruoyi-ui/src/views/monitor/job/index.vue b/ruoyi-ui/src/views/monitor/job/index.vue index a97477b0c..b8284ab91 100644 --- a/ruoyi-ui/src/views/monitor/job/index.vue +++ b/ruoyi-ui/src/views/monitor/job/index.vue @@ -75,7 +75,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['monitor:job:export']" >导出 @@ -306,8 +305,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -510,7 +507,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/monitor/job/export', this.queryParams); + this.download('monitor/job/export', { + ...this.queryParams + }, `job_${new Date().getTime()}.xlsx`) } } }; diff --git a/ruoyi-ui/src/views/monitor/job/log.vue b/ruoyi-ui/src/views/monitor/job/log.vue index fca1af40e..35b778829 100644 --- a/ruoyi-ui/src/views/monitor/job/log.vue +++ b/ruoyi-ui/src/views/monitor/job/log.vue @@ -89,7 +89,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['monitor:job:export']" >导出 @@ -185,7 +184,7 @@ \ No newline at end of file + diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue index 6daa8679c..92b78c98b 100644 --- a/ruoyi-ui/src/views/system/dict/index.vue +++ b/ruoyi-ui/src/views/system/dict/index.vue @@ -94,7 +94,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:dict:export']" >导出 @@ -202,8 +201,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -338,7 +335,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/dict/type/export', this.queryParams); + this.download('system/dict/type/export', { + ...this.queryParams + }, `type_${new Date().getTime()}.xlsx`) }, /** 刷新缓存按钮操作 */ handleRefreshCache() { @@ -348,4 +347,4 @@ export default { } } }; - \ No newline at end of file + diff --git a/ruoyi-ui/src/views/system/post/index.vue b/ruoyi-ui/src/views/system/post/index.vue index 8f823f39b..02698da38 100644 --- a/ruoyi-ui/src/views/system/post/index.vue +++ b/ruoyi-ui/src/views/system/post/index.vue @@ -74,7 +74,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:post:export']" >导出 @@ -169,8 +168,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -305,7 +302,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/post/export', this.queryParams); + this.download('system/post/export', { + ...this.queryParams + }, `post_${new Date().getTime()}.xlsx`) } } }; diff --git a/ruoyi-ui/src/views/system/role/index.vue b/ruoyi-ui/src/views/system/role/index.vue index 9ca11c0c0..a2a412072 100644 --- a/ruoyi-ui/src/views/system/role/index.vue +++ b/ruoyi-ui/src/views/system/role/index.vue @@ -94,7 +94,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:role:export']" >导出 @@ -270,8 +269,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -613,8 +610,10 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/role/export', this.queryParams); + this.download('system/role/export', { + ...this.queryParams + }, `role_${new Date().getTime()}.xlsx`) } } }; - \ No newline at end of file + diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue index 4faa25020..4d86a14ab 100644 --- a/ruoyi-ui/src/views/system/user/index.vue +++ b/ruoyi-ui/src/views/system/user/index.vue @@ -131,7 +131,6 @@ plain icon="el-icon-download" size="mini" - :loading="exportLoading" @click="handleExport" v-hasPermi="['system:user:export']" >导出 @@ -360,8 +359,6 @@ export default { return { // 遮罩层 loading: true, - // 导出遮罩层 - exportLoading: false, // 选中数组 ids: [], // 非单个禁用 @@ -643,7 +640,9 @@ export default { }, /** 导出按钮操作 */ handleExport() { - this.$download.excel('/system/user/export', this.queryParams); + this.download('system/user/export', { + ...this.queryParams + }, `user_${new Date().getTime()}.xlsx`) }, /** 导入按钮操作 */ handleImport() { @@ -652,7 +651,9 @@ export default { }, /** 下载模板操作 */ importTemplate() { - this.$download.excel('/system/user/importTemplate'); + this.download('system/user/importTemplate', { + ...this.queryParams + }, `user_template_${new Date().getTime()}.xlsx`) }, // 文件上传中处理 handleFileUploadProgress(event, file, fileList) { @@ -672,4 +673,4 @@ export default { } } }; - \ No newline at end of file +