Skip to content

Commit b411505

Browse files
JavaLionLigitee-org
authored andcommitted
!255 发布 5.5.2-2.5.2 版本 2025年最后一版
Merge pull request !255 from 疯狂的狮子Li/dev
2 parents 52ea889 + 1e5f898 commit b411505

File tree

13 files changed

+248
-57
lines changed

13 files changed

+248
-57
lines changed

.eslintrc-auto-import.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
"MaybeRefOrGetter": true,
1818
"PropType": true,
1919
"Ref": true,
20+
"Slot": true,
21+
"Slots": true,
2022
"VNode": true,
2123
"WritableComputedRef": true,
2224
"acceptHMRUpdate": true,
@@ -35,6 +37,7 @@
3537
"createInjectionState": true,
3638
"createPinia": true,
3739
"createReactiveFn": true,
40+
"createRef": true,
3841
"createReusableTemplate": true,
3942
"createSharedComposable": true,
4043
"createTemplatePromise": true,
@@ -277,6 +280,7 @@
277280
"useThrottleFn": true,
278281
"useThrottledRefHistory": true,
279282
"useTimeAgo": true,
283+
"useTimeAgoIntl": true,
280284
"useTimeout": true,
281285
"useTimeoutFn": true,
282286
"useTimeoutPoll": true,
@@ -315,9 +319,6 @@
315319
"watchThrottled": true,
316320
"watchTriggerable": true,
317321
"watchWithFilter": true,
318-
"whenever": true,
319-
"Slot": true,
320-
"Slots": true,
321-
"createRef": true
322+
"whenever": true
322323
}
323324
}

package.json

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://json.schemastore.org/package",
33
"name": "ruoyi-vue-plus",
4-
"version": "5.5.1-2.5.1",
4+
"version": "5.5.2-2.5.2",
55
"description": "RuoYi-Vue-Plus多租户管理系统",
66
"author": "LionLi",
77
"license": "MIT",
@@ -20,65 +20,65 @@
2020
"url": "https://gitee.com/JavaLionLi/plus-ui.git"
2121
},
2222
"dependencies": {
23-
"@element-plus/icons-vue": "2.3.1",
24-
"@highlightjs/vue-plugin": "2.1.0",
23+
"@element-plus/icons-vue": "2.3.2",
24+
"@highlightjs/vue-plugin": "2.1.2",
2525
"@vueup/vue-quill": "1.2.0",
26-
"@vueuse/core": "13.1.0",
26+
"@vueuse/core": "13.9.0",
2727
"animate.css": "4.1.1",
2828
"await-to-js": "3.0.0",
29-
"axios": "1.8.4",
29+
"axios": "1.13.1",
3030
"crypto-js": "4.2.0",
3131
"echarts": "5.6.0",
32-
"element-plus": "2.9.8",
32+
"element-plus": "2.11.7",
3333
"file-saver": "2.0.5",
34-
"highlight.js": "11.9.0",
34+
"highlight.js": "11.11.1",
3535
"image-conversion": "2.1.1",
3636
"js-cookie": "3.0.5",
37-
"jsencrypt": "3.3.2",
37+
"jsencrypt": "3.5.4",
3838
"nprogress": "0.2.0",
39-
"pinia": "3.0.2",
39+
"pinia": "3.0.3",
4040
"screenfull": "6.0.2",
41-
"vue": "3.5.13",
42-
"vue-cropper": "1.1.1",
43-
"vue-i18n": "11.1.3",
44-
"vue-json-pretty": "2.4.0",
45-
"vue-router": "4.5.0",
41+
"vue": "3.5.22",
42+
"vue-cropper": "1.1.4",
43+
"vue-i18n": "11.1.12",
44+
"vue-json-pretty": "2.6.0",
45+
"vue-router": "4.6.3",
4646
"vue-types": "6.0.0",
47-
"vxe-table": "4.13.7"
47+
"vxe-table": "4.17.7"
4848
},
4949
"devDependencies": {
50-
"@iconify/json": "^2.2.276",
50+
"@iconify/json": "^2.2.403",
5151
"@types/crypto-js": "4.2.2",
5252
"@types/file-saver": "2.0.7",
5353
"@types/js-cookie": "3.0.6",
54-
"@types/node": "^22.13.4",
54+
"@types/node": "^22.19.0",
5555
"@types/nprogress": "0.2.3",
56-
"@unocss/preset-attributify": "66.5.2",
57-
"@unocss/preset-icons": "66.5.2",
58-
"@unocss/preset-uno": "66.5.2",
59-
"@vitejs/plugin-vue": "5.2.3",
60-
"@vue/compiler-sfc": "3.5.13",
56+
"@unocss/preset-attributify": "66.5.4",
57+
"@unocss/preset-icons": "66.5.4",
58+
"@unocss/preset-uno": "66.5.4",
59+
"@vitejs/plugin-vue": "5.2.4",
60+
"@vue/compiler-sfc": "3.5.22",
6161
"@vue/eslint-config-prettier": "10.2.0",
62-
"@vue/eslint-config-typescript": "14.4.0",
63-
"autoprefixer": "10.4.20",
64-
"eslint": "9.21.0",
65-
"eslint-plugin-prettier": "5.2.3",
66-
"eslint-plugin-vue": "9.32.0",
67-
"globals": "16.0.0",
68-
"prettier": "3.5.2",
69-
"sass": "1.87.0",
70-
"typescript": "~5.8.3",
71-
"unocss": "66.5.2",
72-
"unplugin-auto-import": "19.1.2",
73-
"unplugin-icons": "22.1.0",
74-
"unplugin-vue-components": "28.5.0",
62+
"@vue/eslint-config-typescript": "14.6.0",
63+
"autoprefixer": "10.4.21",
64+
"eslint": "9.39.1",
65+
"eslint-plugin-prettier": "5.5.4",
66+
"eslint-plugin-vue": "9.33.0",
67+
"globals": "16.5.0",
68+
"prettier": "3.6.2",
69+
"sass": "1.93.3",
70+
"typescript": "~5.9.3",
71+
"unocss": "66.5.4",
72+
"unplugin-auto-import": "19.3.0",
73+
"unplugin-icons": "22.5.0",
74+
"unplugin-vue-components": "28.8.0",
7575
"unplugin-vue-setup-extend-plus": "1.0.1",
76-
"vite": "6.3.2",
76+
"vite": "6.4.1",
7777
"vite-plugin-compression": "0.5.1",
78-
"vite-plugin-svg-icons-ng": "^1.4.0",
79-
"vite-plugin-vue-devtools": "7.7.5",
80-
"vitest": "3.1.2",
81-
"vue-tsc": "^2.2.8"
78+
"vite-plugin-svg-icons-ng": "^1.5.2",
79+
"vite-plugin-vue-devtools": "8.0.3",
80+
"vitest": "3.2.4",
81+
"vue-tsc": "^2.2.12"
8282
},
8383
"overrides": {
8484
"quill": "2.0.2"

src/api/system/social/auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import request from '@/utils/request';
22

3-
// 绑定账号
4-
export function authBinding(source: string, tenantId: string) {
3+
// 获取跳转URL
4+
export function authRouterUrl(source: string, tenantId: string) {
55
return request({
66
url: '/auth/binding/' + source,
77
method: 'get',

src/components/DictTag/index.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div>
33
<template v-for="(item, index) in options">
4-
<template v-if="values.includes(item.value)">
4+
<template v-if="isValueMatch(item.value)">
55
<span
66
v-if="(item.elTagType === 'default' || item.elTagType === '') && (item.elTagClass === '' || item.elTagClass == null)"
77
:key="item.value"
@@ -50,6 +50,7 @@ const props = withDefaults(defineProps<Props>(), {
5050
5151
const values = computed(() => {
5252
if (props.value === '' || props.value === null || typeof props.value === 'undefined') return [];
53+
if (typeof props.value === 'number' || typeof props.value === 'boolean') return [props.value]
5354
return Array.isArray(props.value) ? props.value.map((item) => '' + item) : String(props.value).split(props.separator);
5455
});
5556
@@ -58,7 +59,7 @@ const unmatch = computed(() => {
5859
// 传入值为非数组
5960
let unmatch = false; // 添加一个标志来判断是否有未匹配项
6061
values.value.forEach((item) => {
61-
if (!props.options.some((v) => v.value === item)) {
62+
if (!props.options.some((v) => v.value == item)) {
6263
unmatch = true; // 如果有未匹配项,将标志设置为true
6364
}
6465
});
@@ -85,6 +86,10 @@ const handleArray = (array: Array<string | number>) => {
8586
return pre + ' ' + cur;
8687
});
8788
};
89+
90+
const isValueMatch = (itemValue: any) => {
91+
return values.value.some(val => val == itemValue)
92+
}
8893
</script>
8994

9095
<style lang="scss" scoped>

src/components/Process/submitVerify.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<el-checkbox value="3" name="type">短信</el-checkbox>
99
</el-checkbox-group>
1010
</el-form-item>
11-
<el-form-item label="附件">
11+
<el-form-item label="附件" v-if="buttonObj.file">
1212
<fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
1313
</el-form-item>
1414
<el-form-item label="抄送" v-if="buttonObj.copy">

src/main.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ import ElementIcons from '@/plugins/svgicon';
2828
// permission control
2929
import './permission';
3030

31+
// 开发者工具保护
32+
import { initDevToolsProtection } from '@/utils/devtools-protection';
33+
3134
// 国际化
3235
import i18n from '@/lang/index';
3336

@@ -55,3 +58,6 @@ app.use(plugins);
5558
directive(app);
5659

5760
app.mount('#app');
61+
62+
// 初始化开发者工具保护(仅生产环境)
63+
initDevToolsProtection();

src/utils/devtools-protection.ts

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/**
2+
* 开发者工具保护
3+
* 检测开发者工具是否打开,如果打开则循环执行 debugger 阻止调试
4+
*/
5+
6+
// 检测开发者工具是否打开
7+
function detectDevTools(): boolean {
8+
try {
9+
// 方法1: 检测窗口尺寸差异(最可靠的方法)
10+
const widthThreshold = 160; // 开发者工具最小宽度
11+
const heightThreshold = 160; // 开发者工具最小高度
12+
13+
const widthDiff = window.outerWidth - window.innerWidth;
14+
const heightDiff = window.outerHeight - window.innerHeight;
15+
16+
if (widthDiff > widthThreshold || heightDiff > heightThreshold) {
17+
return true;
18+
}
19+
20+
// 方法2: 检测 debugger 执行时间(最准确的方法)
21+
const start = performance.now();
22+
debugger; // 这个 debugger 用于检测,不会被移除
23+
const end = performance.now();
24+
const timeDiff = end - start;
25+
26+
// 如果 debugger 被跳过(开发者工具关闭),时间差会很小(通常 < 1ms)
27+
// 如果 debugger 暂停(开发者工具打开),时间差会很大(通常 > 100ms)
28+
// 降低阈值以提高检测灵敏度
29+
if (timeDiff > 10) {
30+
return true;
31+
}
32+
33+
// 方法3: 检测控制台对象
34+
let devtoolsDetected = false;
35+
const element = document.createElement('div');
36+
Object.defineProperty(element, 'id', {
37+
get: function () {
38+
devtoolsDetected = true;
39+
return '';
40+
}
41+
});
42+
43+
// 使用 console 来触发 getter(仅在开发者工具打开时)
44+
try {
45+
console.log(element);
46+
console.clear();
47+
} catch (e) {
48+
// 忽略错误
49+
}
50+
51+
if (devtoolsDetected) {
52+
return true;
53+
}
54+
55+
// 方法4: 检测控制台是否被重写(开发者工具打开时)
56+
const devtoolsRegex = /./;
57+
// @ts-expect-error - 动态添加属性
58+
devtoolsRegex.toString = function () {
59+
// @ts-expect-error - 动态添加属性
60+
this.opened = true;
61+
};
62+
console.log('%c', devtoolsRegex);
63+
// @ts-expect-error - 检查动态添加的属性
64+
if (devtoolsRegex.opened) {
65+
return true;
66+
}
67+
} catch (e) {
68+
// 如果检测过程中出错,默认返回 false
69+
return false;
70+
}
71+
72+
return false;
73+
}
74+
75+
// 开发者工具保护主函数
76+
export function initDevToolsProtection(): void {
77+
// 可以通过环境变量控制是否启用
78+
// 生产环境默认启用,开发环境可以通过 VITE_ENABLE_ANTI_DEBUG=true 来启用测试
79+
const isProduction = import.meta.env.MODE === 'production';
80+
const enableAntiDebug = import.meta.env.VITE_ENABLE_ANTI_DEBUG === 'true' || isProduction;
81+
82+
if (!enableAntiDebug) {
83+
return;
84+
}
85+
86+
let devToolsOpen = false;
87+
let debuggerInterval: number | null = null;
88+
89+
// 立即执行一次检测
90+
const initialCheck = detectDevTools();
91+
if (initialCheck) {
92+
devToolsOpen = true;
93+
debuggerInterval = window.setInterval(() => {
94+
debugger; // 循环执行 debugger
95+
}, 50); // 更频繁的 debugger,每 50ms 一次
96+
}
97+
98+
// 循环检测开发者工具(更频繁的检测)
99+
const checkInterval = setInterval(() => {
100+
const isOpen = detectDevTools();
101+
102+
if (isOpen && !devToolsOpen) {
103+
// 开发者工具刚打开
104+
devToolsOpen = true;
105+
106+
// 开始循环执行 debugger(更频繁)
107+
if (debuggerInterval === null) {
108+
debuggerInterval = window.setInterval(() => {
109+
debugger; // 循环执行 debugger
110+
}, 50); // 每 50ms 执行一次,更激进
111+
}
112+
} else if (!isOpen && devToolsOpen) {
113+
// 开发者工具关闭了
114+
devToolsOpen = false;
115+
116+
// 停止循环 debugger
117+
if (debuggerInterval !== null) {
118+
clearInterval(debuggerInterval);
119+
debuggerInterval = null;
120+
}
121+
}
122+
}, 500); // 每 500ms 检测一次,更频繁
123+
124+
// 页面卸载时清理
125+
window.addEventListener('beforeunload', () => {
126+
clearInterval(checkInterval);
127+
if (debuggerInterval !== null) {
128+
clearInterval(debuggerInterval);
129+
}
130+
});
131+
132+
// 额外的检测:监听窗口大小变化
133+
let lastWidth = window.innerWidth;
134+
let lastHeight = window.innerHeight;
135+
136+
window.addEventListener('resize', () => {
137+
const currentWidth = window.innerWidth;
138+
const currentHeight = window.innerHeight;
139+
140+
// 如果窗口尺寸变化很大,可能是开发者工具打开/关闭
141+
if (Math.abs(currentWidth - lastWidth) > 200 || Math.abs(currentHeight - lastHeight) > 200) {
142+
// 重新检测
143+
const isOpen = detectDevTools();
144+
if (isOpen && !devToolsOpen) {
145+
devToolsOpen = true;
146+
if (debuggerInterval === null) {
147+
debuggerInterval = window.setInterval(() => {
148+
debugger; // 循环执行 debugger
149+
}, 50); // 更频繁的 debugger
150+
}
151+
}
152+
}
153+
154+
lastWidth = currentWidth;
155+
lastHeight = currentHeight;
156+
});
157+
}
158+

src/utils/jsencrypt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min.js';
1+
import JSEncrypt from 'jsencrypt';
22
// 密钥对生成 http://web.chacuo.net/netrsakeypair
33

44
const publicKey = import.meta.env.VITE_APP_RSA_PUBLIC_KEY;

0 commit comments

Comments
 (0)