4 Commits

Author SHA1 Message Date
RuoYi
b99039b609 优化页签滚动条层级 2026-06-10 22:33:46 +08:00
RuoYi
f6763c1ab6 升级项目相关依赖到最新 2026-06-10 19:29:38 +08:00
RuoYi
9213f18332 优化代码 2026-06-10 19:29:28 +08:00
RuoYi
8f8b4cd50b 禁止html后缀文件上传 2026-06-10 19:29:10 +08:00
17 changed files with 100 additions and 76 deletions

14
pom.xml
View File

@@ -17,27 +17,27 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version> <java.version>17</java.version>
<spring-boot.version>3.5.11</spring-boot.version> <spring-boot.version>3.5.14</spring-boot.version>
<mybatis-spring-boot.version>3.0.5</mybatis-spring-boot.version> <mybatis-spring-boot.version>3.0.5</mybatis-spring-boot.version>
<druid.version>1.2.28</druid.version> <druid.version>1.2.28</druid.version>
<yauaa.version>8.1.0</yauaa.version> <yauaa.version>8.1.1</yauaa.version>
<kaptcha.version>2.3.3</kaptcha.version> <kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>2.1.1</pagehelper.boot.version> <pagehelper.boot.version>2.1.1</pagehelper.boot.version>
<fastjson.version>2.0.61</fastjson.version> <fastjson.version>2.0.62</fastjson.version>
<oshi.version>6.10.0</oshi.version> <oshi.version>7.3.0</oshi.version>
<commons.io.version>2.21.0</commons.io.version> <commons.io.version>2.22.0</commons.io.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version> <jwt.version>0.9.1</jwt.version>
<jaxb-api.version>2.3.1</jaxb-api.version> <jaxb-api.version>2.3.1</jaxb-api.version>
<springdoc.version>2.8.16</springdoc.version> <springdoc.version>2.8.17</springdoc.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<!-- SpringBoot的依赖配置--> <!-- SpringBoot的依赖配置 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId> <artifactId>spring-boot-dependencies</artifactId>

View File

@@ -30,7 +30,7 @@ public class MimeTypeUtils
// 图片 // 图片
"bmp", "gif", "jpg", "jpeg", "png", "bmp", "gif", "jpg", "jpeg", "png",
// word excel powerpoint // word excel powerpoint
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt",
// 压缩文件 // 压缩文件
"rar", "zip", "gz", "bz2", "rar", "zip", "gz", "bz2",
// 视频格式 // 视频格式

View File

@@ -315,7 +315,7 @@
<script setup lang="ts" name="${BusinessName}"> <script setup lang="ts" name="${BusinessName}">
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}" import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"
#if($genView) #if($genView)
import ${BusinessName}ViewDrawer from "./view" import ${BusinessName}ViewDrawer from "./view.vue"
#end #end
import type { ${ClassName}, ${BusinessName}QueryParams } from "@/types/api/${moduleName}/${businessName}" import type { ${ClassName}, ${BusinessName}QueryParams } from "@/types/api/${moduleName}/${businessName}"
import type { TreeSelect } from '@/types/api/common' import type { TreeSelect } from '@/types/api/common'

View File

@@ -394,7 +394,7 @@ import type { ${ClassName}, ${BusinessName}QueryParams } from "@/types/api/${mod
#end #end
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}" import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"
#if($genView) #if($genView)
import ${BusinessName}ViewDrawer from "./view" import ${BusinessName}ViewDrawer from "./view.vue"
#end #end
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()

View File

@@ -34,7 +34,7 @@ export default {
} }
}, },
created() { created() {
if(this.defaultTheme !== ORIGINAL_THEME) { if (this.defaultTheme !== ORIGINAL_THEME) {
this.setTheme(this.defaultTheme) this.setTheme(this.defaultTheme)
} }
}, },

View File

@@ -1,4 +1,4 @@
/** /**
* v-hasPermi 操作权限处理 * v-hasPermi 操作权限处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */

View File

@@ -1,4 +1,4 @@
/** /**
* v-hasRole 角色权限处理 * v-hasRole 角色权限处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */

View File

@@ -109,7 +109,7 @@ export default {
return { return {
'--chrome-tab-active-bg': this.mixHexWithWhite(primary, 0.15), '--chrome-tab-active-bg': this.mixHexWithWhite(primary, 0.15),
'--chrome-tab-text-active': primary, '--chrome-tab-text-active': primary,
'--chrome-wing-r': '14px' '--chrome-wing-r': '10px'
} }
} }
}, },
@@ -610,16 +610,19 @@ $tags-bar-height: 34px;
background: #f5f7fa !important; background: #f5f7fa !important;
border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0;
color: #303133 !important; color: #303133 !important;
z-index: 2;
} }
&.active { &.active {
height: 31px; height: 33px;
min-height: 31px; min-height: 33px;
padding: 0 14px; padding: 0 14px;
z-index: 3;
color: var(--chrome-tab-text-active) !important; color: var(--chrome-tab-text-active) !important;
font-weight: 500; font-weight: 500;
background: var(--chrome-tab-active-bg) !important; background: var(--chrome-tab-active-bg) !important;
border: none !important; border: none !important;
border-bottom: 2px solid var(--chrome-tab-active-bg) !important;
border-radius: var(--chrome-wing-r) var(--chrome-wing-r) 0 0; border-radius: var(--chrome-wing-r) var(--chrome-wing-r) 0 0;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
@@ -690,12 +693,33 @@ $tags-bar-height: 34px;
.el-scrollbar__bar { .el-scrollbar__bar {
opacity: 0; opacity: 0;
transition: opacity 0.3s; transition: opacity 0.3s;
z-index: 10;
.tags-view-container:hover & { .tags-view-container:hover & {
opacity: 1; opacity: 1;
} }
} }
.tags-view-container--chrome & {
.el-scrollbar {
position: relative;
}
.el-scrollbar__wrap {
&::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
}
scrollbar-width: none;
-ms-overflow-style: none;
}
.el-scrollbar__bar.is-horizontal {
z-index: 20;
height: 6px !important;
}
}
.tags-view-item { .tags-view-item {
.el-icon-close { .el-icon-close {
width: 16px; width: 16px;

View File

@@ -76,10 +76,10 @@ export default {
this.routers.map((router) => { this.routers.map((router) => {
for (var item in router.children) { for (var item in router.children) {
if (router.children[item].parentPath === undefined) { if (router.children[item].parentPath === undefined) {
if(router.path === "/") { if (router.path === "/") {
router.children[item].path = "/" + router.children[item].path router.children[item].path = "/" + router.children[item].path
} else { } else {
if(!isHttp(router.children[item].path)) { if (!isHttp(router.children[item].path)) {
router.children[item].path = router.path + "/" + router.children[item].path router.children[item].path = router.path + "/" + router.children[item].path
} }
} }
@@ -100,7 +100,7 @@ export default {
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")) activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"))
this.$store.dispatch('app/toggleSideBarHide', false) this.$store.dispatch('app/toggleSideBarHide', false)
} }
} else if(!this.$route.children) { } else if (!this.$route.children) {
activePath = path activePath = path
this.$store.dispatch('app/toggleSideBarHide', true) this.$store.dispatch('app/toggleSideBarHide', true)
} }
@@ -156,7 +156,7 @@ export default {
} }
}) })
} }
if(routes.length > 0) { if (routes.length > 0) {
this.$store.commit("SET_SIDEBAR_ROUTERS", routes) this.$store.commit("SET_SIDEBAR_ROUTERS", routes)
} else { } else {
this.$store.dispatch('app/toggleSideBarHide', true) this.$store.dispatch('app/toggleSideBarHide', true)

View File

@@ -44,11 +44,11 @@ router.beforeEach((to, from, next) => {
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
}) })
}).catch(err => { }).catch(err => {
store.dispatch('LogOut').then(() => { store.dispatch('LogOut').then(() => {
Message.error(err) Message.error(err)
next({ path: '/' }) next({ path: '/' })
})
}) })
})
} else { } else {
next() next()
} }

View File

@@ -123,7 +123,7 @@ const mutations = {
if (i > -1) { if (i > -1) {
state.cachedViews.splice(i, 1) state.cachedViews.splice(i, 1)
} }
if(item.meta.link) { if (item.meta.link) {
const fi = state.iframeViews.findIndex(v => v.path === item.path) const fi = state.iframeViews.findIndex(v => v.path === item.path)
state.iframeViews.splice(fi, 1) state.iframeViews.splice(fi, 1)
} }
@@ -144,7 +144,7 @@ const mutations = {
if (i > -1) { if (i > -1) {
state.cachedViews.splice(i, 1) state.cachedViews.splice(i, 1)
} }
if(item.meta.link) { if (item.meta.link) {
const fi = state.iframeViews.findIndex(v => v.path === item.path) const fi = state.iframeViews.findIndex(v => v.path === item.path)
state.iframeViews.splice(fi, 1) state.iframeViews.splice(fi, 1)
} }

View File

@@ -1,7 +1,7 @@
import store from '@/store' import store from '@/store'
import router from '@/router' import router from '@/router'
import cache from '@/plugins/cache' import cache from '@/plugins/cache'
import { MessageBox, } from 'element-ui' import { MessageBox } from 'element-ui'
import { login, logout, getInfo } from '@/api/login' import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
import { isHttp, isEmpty } from "@/utils/validate" import { isHttp, isEmpty } from "@/utils/validate"

View File

@@ -68,59 +68,59 @@ service.interceptors.request.use(config => {
} }
return config return config
}, error => { }, error => {
console.log(error) console.log(error)
Promise.reject(error) Promise.reject(error)
}) })
// 响应拦截器 // 响应拦截器
service.interceptors.response.use(res => { service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态 // 未设置状态码则默认成功状态
const code = res.data.code || 200 const code = res.data.code || 200
// 获取错误信息 // 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default'] const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回 // 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data return res.data
} }
if (code === 401) { if (code === 401) {
if (!isRelogin.show) { if (!isRelogin.show) {
isRelogin.show = true isRelogin.show = true
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false isRelogin.show = false
store.dispatch('LogOut').then(() => { store.dispatch('LogOut').then(() => {
location.href = '/index' location.href = '/index'
}) })
}).catch(() => { }).catch(() => {
isRelogin.show = false isRelogin.show = false
}) })
} }
return Promise.reject('无效的会话,或者会话已过期,请重新登录。') return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) { } else if (code === 500) {
Message({ message: msg, type: 'error' }) Message({ message: msg, type: 'error' })
return Promise.reject(new Error(msg)) return Promise.reject(new Error(msg))
} else if (code === 601) { } else if (code === 601) {
Message({ message: msg, type: 'warning' }) Message({ message: msg, type: 'warning' })
return Promise.reject('error') return Promise.reject('error')
} else if (code !== 200) { } else if (code !== 200) {
Notification.error({ title: msg }) Notification.error({ title: msg })
return Promise.reject('error') return Promise.reject('error')
} else { } else {
return res.data return res.data
}
},
error => {
console.log('err' + error)
let { message } = error
if (message == "Network Error") {
message = "后端接口连接异常"
} else if (message.includes("timeout")) {
message = "系统接口请求超时"
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.slice(-3) + "异常"
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
} }
},
error => {
console.log('err' + error)
let { message } = error
if (message == "Network Error") {
message = "后端接口连接异常"
} else if (message.includes("timeout")) {
message = "系统接口请求超时"
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.slice(-3) + "异常"
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
) )
// 通用下载方法 // 通用下载方法

View File

@@ -86,7 +86,7 @@ export function selectDictLabel(datas, value) {
// 回显数据字典(字符串、数组) // 回显数据字典(字符串、数组)
export function selectDictLabels(datas, value, separator) { export function selectDictLabels(datas, value, separator) {
if (value === undefined || value.length ===0) { if (value === undefined || value.length === 0) {
return "" return ""
} }
if (Array.isArray(value)) { if (Array.isArray(value)) {

View File

@@ -527,7 +527,7 @@ export default {
}, },
/** 选择角色权限范围触发 */ /** 选择角色权限范围触发 */
dataScopeSelectChange(value) { dataScopeSelectChange(value) {
if(value !== '2') { if (value !== '2') {
this.$refs.dept.setCheckedKeys([]) this.$refs.dept.setCheckedKeys([])
} }
}, },

View File

@@ -316,7 +316,7 @@ export default {
}, },
/** 选择生成模板触发 */ /** 选择生成模板触发 */
tplSelectChange(value) { tplSelectChange(value) {
if(value !== 'sub') { if (value !== 'sub') {
this.info.subTableName = '' this.info.subTableName = ''
this.info.subTableFkName = '' this.info.subTableFkName = ''
} }

View File

@@ -262,7 +262,7 @@ export default {
this.$modal.msgError("请选择要生成的数据") this.$modal.msgError("请选择要生成的数据")
return return
} }
if(row.genType === "1") { if (row.genType === "1") {
genCode(row.tableName).then(() => { genCode(row.tableName).then(() => {
this.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath) this.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath)
}) })