From 2c81b1478c098fd60e3d74117868a8e413836221 Mon Sep 17 00:00:00 2001 From: gaoxq <376340421@qq.com> Date: Sun, 8 Mar 2026 16:52:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E5=B1=8F=E9=A1=B9=E7=9B=AE=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 13 +++ screen-vue/src/api/bizFiles.js | 13 +++ screen-vue/src/api/bizModule.js | 23 +++++ screen-vue/src/api/bizRole.js | 11 +++ screen-vue/src/api/bizUser.js | 3 +- screen-vue/src/utils/request.js | 93 +++++++++++++++++-- .../src/views/database/screen/index.vue | 16 ++-- screen-vue/src/views/database/screen/list.vue | 38 +++++--- screen-vue/src/views/database/screen/role.vue | 71 +++++++++++++- screen-vue/src/views/screen/Sys/index.vue | 8 ++ screen-vue/src/views/system/menu/list.vue | 9 -- screen-vue/src/views/system/role/index.vue | 6 +- screen-vue/src/views/system/role/list.vue | 32 ++++--- screen-vue/src/views/system/user/list.vue | 9 +- .../Model/JoinDao/ModuleLeftUser.java | 33 +++++++ .../mini/mybigscreen/Model/ModuleUser.java | 5 + .../biz/controller/HomeModuleController.java | 48 ++++++++-- .../controller/HomeModuleUserController.java | 29 +++++- .../biz/controller/HomeRoleController.java | 29 +++++- .../biz/controller/HomeUserController.java | 8 +- .../biz/domain/HomeModuleUser.java | 2 +- 21 files changed, 424 insertions(+), 75 deletions(-) create mode 100644 screen-vue/src/api/bizFiles.js create mode 100644 screen-vue/src/views/screen/Sys/index.vue create mode 100644 src/main/java/com/mini/mybigscreen/Model/JoinDao/ModuleLeftUser.java diff --git a/pom.xml b/pom.xml index a2157ab..ac8fd60 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,19 @@ 5.8.31 + + org.apache.poi + poi + 5.2.5 + + + + + org.apache.poi + poi-ooxml + 5.2.5 + + com.baomidou diff --git a/screen-vue/src/api/bizFiles.js b/screen-vue/src/api/bizFiles.js new file mode 100644 index 0000000..9782a47 --- /dev/null +++ b/screen-vue/src/api/bizFiles.js @@ -0,0 +1,13 @@ +import request from '@/utils/request'; + +/** + * 导出用户信息 + */ +export function download(params) { + return request({ + url: '/biz/homeFiles/dwonload', + method: 'get', + params, + responseType: 'blob' + }); +} \ No newline at end of file diff --git a/screen-vue/src/api/bizModule.js b/screen-vue/src/api/bizModule.js index ac9d59e..7b32b31 100644 --- a/screen-vue/src/api/bizModule.js +++ b/screen-vue/src/api/bizModule.js @@ -1,5 +1,6 @@ import request from '@/utils/request' + /** * 获取指标信息列表 */ @@ -11,6 +12,28 @@ export function getHomeModuleList(params) { }) } +/** + * 获取指标信息列表 + */ +export function getHomeModuleListAll(params) { + return request({ + url: '/biz/homeModule/listAll', + method: 'get', + params: params + }) +} + +/** + * 删除信息列表 + */ +export function getHomeModuleSave(data) { + return request({ + url: '/biz/homeModule/save', + method: 'post', + data + }) +} + /** * 删除信息列表 */ diff --git a/screen-vue/src/api/bizRole.js b/screen-vue/src/api/bizRole.js index c1432df..2ef0ea2 100644 --- a/screen-vue/src/api/bizRole.js +++ b/screen-vue/src/api/bizRole.js @@ -11,6 +11,17 @@ export function getHomeRoleList(params) { }) } +/** + * 获取指标信息列表 + */ +export function getHomeRoleUserList(params) { + return request({ + url: '/biz/homeRole/userList', + method: 'get', + params: params + }) +} + /** * 获取角色授权的菜单 */ diff --git a/screen-vue/src/api/bizUser.js b/screen-vue/src/api/bizUser.js index 011ebaa..5ec5ff6 100644 --- a/screen-vue/src/api/bizUser.js +++ b/screen-vue/src/api/bizUser.js @@ -42,4 +42,5 @@ export function getHomeUserDelete(params) { method: 'post', params: params }) -} \ No newline at end of file +} + diff --git a/screen-vue/src/utils/request.js b/screen-vue/src/utils/request.js index d4ca119..f060433 100644 --- a/screen-vue/src/utils/request.js +++ b/screen-vue/src/utils/request.js @@ -1,5 +1,5 @@ import axios from 'axios' -import { ElMessage } from 'element-plus' +import { ElMessage, ElMessageBox } from 'element-plus' import router from '@/router' const service = axios.create({ @@ -39,27 +39,32 @@ service.interceptors.response.use( (response) => { const res = response.data; - // 1. 处理登录失效 + if (response.config.responseType === 'blob') { + return handleFileExport(response); + } + if (res.code === 401) { handleLoginExpired(); return Promise.reject(res); } - // 2. 处理业务成功 if (res.code === 200) { return res.data; } - // 3. 处理其他业务错误(如500) ElMessage.error(res.msg || '请求失败'); return Promise.reject(res); }, (error) => { const requestUrl = error?.config?.url || ''; const isWhite = WHITE_LIST.some(item => requestUrl.includes(item)); - + if (error.config?.responseType === 'blob') { + handleFileExportError(error); + return Promise.reject(error); + } + if (isWhite) { - const errMsg = error?.response?.data?.msg || '登录请求失败,请检查网络或账号信息'; + const errMsg = error?.response?.data?.msg || '登录请求失败,请检查网络或账号信息'; ElMessage.error(errMsg); return Promise.reject(error); } @@ -70,7 +75,7 @@ service.interceptors.response.use( } if (!error.response) { - ElMessage.error('网络异常,请检查网络连接后重试'); + ElMessage.error('网络异常,请检查网络连接后重试'); return Promise.reject(error); } @@ -82,7 +87,79 @@ function handleLoginExpired() { localStorage.removeItem('token'); if (router.currentRoute.path !== '/login') { router.push('/login').catch(() => {}); - ElMessage.error('登录已失效,请重新登录'); + ElMessage.error('登录已失效,请重新登录'); + } +} + +function handleFileExport(response) { + const blob = response.data; + const defaultFileName = 'file.xlsx'; + return new Promise((resolve, reject) => { + if (!blob || blob.size === 0) { + ElMessage.error('文件大小异常,请稍后重试'); + reject(new Error('文件内容为空')); + return; + } + const reader = new FileReader(); + reader.onerror = function() { + reject(new Error('文件解析失败')); + }; + reader.onload = function() { + try { + const res = JSON.parse(reader.result); + ElMessage.error(res.msg || '文件下载失败'); + reject(res); + } catch (e) { + let fileName = defaultFileName; + const disposition = response.headers['content-disposition']; + if (disposition) { + const match = disposition.match(/filename\*=UTF-8''(.+)/i); + if (match && match[1]) { + fileName = decodeURIComponent(match[1]); + } + } + if (response.config.downloadFileName) { + fileName = typeof response.config.downloadFileName === 'function' + ? response.config.downloadFileName(response) + : response.config.downloadFileName; + } + + try { + const url = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.target = '_blank'; + link.rel = 'noopener noreferrer'; + link.href = url; + link.setAttribute('download', fileName); + document.body.appendChild(link); + const clickEvent = new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window + }); + link.dispatchEvent(clickEvent); + setTimeout(() => { + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + }, 100); + resolve(blob); + } catch (downloadError) { + ElMessage.error('文件下载失败,请手动重试'); + reject(downloadError); + } + } + }; + reader.readAsText(blob); + }); +} + +function handleFileExportError(error) { + if (error.response?.status === 401) { + handleLoginExpired(); + } else if (error.message.includes('timeout')) { + ElMessage.error('文件下载超时,请稍后重试'); + } else { + ElMessage.error('文件下载失败,请稍后重试'); } } diff --git a/screen-vue/src/views/database/screen/index.vue b/screen-vue/src/views/database/screen/index.vue index 2557db3..a56c5ea 100644 --- a/screen-vue/src/views/database/screen/index.vue +++ b/screen-vue/src/views/database/screen/index.vue @@ -20,7 +20,7 @@ @@ -43,14 +43,14 @@ import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' import ResizablePage from '@/components/Table/proResizable.vue' import FilterSelect from '@/components/Table/proFilterSelect.vue' import PDialog from '@/components/Dialog/proDialog.vue' -import { getHomeModuleList } from '@/api/bizModule' -import { getHomeModuleUserSave , getHomeModuleUserDelete } from '@/api/bizModuleUser' +import { getHomeModuleListAll, getHomeModuleDelete } from '@/api/bizModule' +import { getHomeModuleUserSave } from '@/api/bizModuleUser' import vUser from './list.vue' import vRole from './role.vue' const FormValues = ref({ - menuId: '' + moduleId: '' }); const listData = ref([]); @@ -61,7 +61,7 @@ const formComponentRef = ref(null) const getListData = async () => { try { - const res = await getHomeModuleList(); + const res = await getHomeModuleListAll(); listData.value = res || [] } catch (error) { console.log(error); @@ -69,7 +69,7 @@ const getListData = async () => { } const handleItemClick = (item) => { - console.log('选中了:', item) + FormValues.value.moduleId = item.moduleId } const handleEdit = (item) => { @@ -85,9 +85,9 @@ const handleDelete = (item) => { }) .then(async () => { const reqParams = { - roleId: item.roleId + moduleId: item.moduleId } - const res = await getHomeModuleUserDelete(reqParams); + const res = await getHomeModuleDelete(reqParams); ElMessage.success(res.msg); getListData(); }) diff --git a/screen-vue/src/views/database/screen/list.vue b/screen-vue/src/views/database/screen/list.vue index e2cc700..8d58b84 100644 --- a/screen-vue/src/views/database/screen/list.vue +++ b/screen-vue/src/views/database/screen/list.vue @@ -40,9 +40,6 @@ 新增 - - 导出 - + + @@ -48,7 +48,7 @@ import vUser from './list.vue' import vRole from './role.vue' const FormValues = ref({ - menuId: '' + roleId: '' }); const listData = ref([]); @@ -67,7 +67,7 @@ const getListData = async () => { } const handleItemClick = (item) => { - console.log('选中了:', item) + FormValues.value.roleId = item.roleId } const handleEdit = (item) => { diff --git a/screen-vue/src/views/system/role/list.vue b/screen-vue/src/views/system/role/list.vue index e2cc700..d82b8d4 100644 --- a/screen-vue/src/views/system/role/list.vue +++ b/screen-vue/src/views/system/role/list.vue @@ -40,9 +40,6 @@ 新增 - - 导出 -