!255 发布 5.5.2-2.5.2 版本 2025年最后一版
Merge pull request !255 from 疯狂的狮子Li/dev
This commit is contained in:
@@ -17,6 +17,8 @@
|
|||||||
"MaybeRefOrGetter": true,
|
"MaybeRefOrGetter": true,
|
||||||
"PropType": true,
|
"PropType": true,
|
||||||
"Ref": true,
|
"Ref": true,
|
||||||
|
"Slot": true,
|
||||||
|
"Slots": true,
|
||||||
"VNode": true,
|
"VNode": true,
|
||||||
"WritableComputedRef": true,
|
"WritableComputedRef": true,
|
||||||
"acceptHMRUpdate": true,
|
"acceptHMRUpdate": true,
|
||||||
@@ -35,6 +37,7 @@
|
|||||||
"createInjectionState": true,
|
"createInjectionState": true,
|
||||||
"createPinia": true,
|
"createPinia": true,
|
||||||
"createReactiveFn": true,
|
"createReactiveFn": true,
|
||||||
|
"createRef": true,
|
||||||
"createReusableTemplate": true,
|
"createReusableTemplate": true,
|
||||||
"createSharedComposable": true,
|
"createSharedComposable": true,
|
||||||
"createTemplatePromise": true,
|
"createTemplatePromise": true,
|
||||||
@@ -277,6 +280,7 @@
|
|||||||
"useThrottleFn": true,
|
"useThrottleFn": true,
|
||||||
"useThrottledRefHistory": true,
|
"useThrottledRefHistory": true,
|
||||||
"useTimeAgo": true,
|
"useTimeAgo": true,
|
||||||
|
"useTimeAgoIntl": true,
|
||||||
"useTimeout": true,
|
"useTimeout": true,
|
||||||
"useTimeoutFn": true,
|
"useTimeoutFn": true,
|
||||||
"useTimeoutPoll": true,
|
"useTimeoutPoll": true,
|
||||||
@@ -315,9 +319,6 @@
|
|||||||
"watchThrottled": true,
|
"watchThrottled": true,
|
||||||
"watchTriggerable": true,
|
"watchTriggerable": true,
|
||||||
"watchWithFilter": true,
|
"watchWithFilter": true,
|
||||||
"whenever": true,
|
"whenever": true
|
||||||
"Slot": true,
|
|
||||||
"Slots": true,
|
|
||||||
"createRef": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
80
package.json
80
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package",
|
"$schema": "https://json.schemastore.org/package",
|
||||||
"name": "ruoyi-vue-plus",
|
"name": "ruoyi-vue-plus",
|
||||||
"version": "5.5.1-2.5.1",
|
"version": "5.5.2-2.5.2",
|
||||||
"description": "RuoYi-Vue-Plus多租户管理系统",
|
"description": "RuoYi-Vue-Plus多租户管理系统",
|
||||||
"author": "LionLi",
|
"author": "LionLi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -20,65 +20,65 @@
|
|||||||
"url": "https://gitee.com/JavaLionLi/plus-ui.git"
|
"url": "https://gitee.com/JavaLionLi/plus-ui.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "2.3.1",
|
"@element-plus/icons-vue": "2.3.2",
|
||||||
"@highlightjs/vue-plugin": "2.1.0",
|
"@highlightjs/vue-plugin": "2.1.2",
|
||||||
"@vueup/vue-quill": "1.2.0",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "13.1.0",
|
"@vueuse/core": "13.9.0",
|
||||||
"animate.css": "4.1.1",
|
"animate.css": "4.1.1",
|
||||||
"await-to-js": "3.0.0",
|
"await-to-js": "3.0.0",
|
||||||
"axios": "1.8.4",
|
"axios": "1.13.1",
|
||||||
"crypto-js": "4.2.0",
|
"crypto-js": "4.2.0",
|
||||||
"echarts": "5.6.0",
|
"echarts": "5.6.0",
|
||||||
"element-plus": "2.9.8",
|
"element-plus": "2.11.7",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"highlight.js": "11.9.0",
|
"highlight.js": "11.11.1",
|
||||||
"image-conversion": "2.1.1",
|
"image-conversion": "2.1.1",
|
||||||
"js-cookie": "3.0.5",
|
"js-cookie": "3.0.5",
|
||||||
"jsencrypt": "3.3.2",
|
"jsencrypt": "3.5.4",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"pinia": "3.0.2",
|
"pinia": "3.0.3",
|
||||||
"screenfull": "6.0.2",
|
"screenfull": "6.0.2",
|
||||||
"vue": "3.5.13",
|
"vue": "3.5.22",
|
||||||
"vue-cropper": "1.1.1",
|
"vue-cropper": "1.1.4",
|
||||||
"vue-i18n": "11.1.3",
|
"vue-i18n": "11.1.12",
|
||||||
"vue-json-pretty": "2.4.0",
|
"vue-json-pretty": "2.6.0",
|
||||||
"vue-router": "4.5.0",
|
"vue-router": "4.6.3",
|
||||||
"vue-types": "6.0.0",
|
"vue-types": "6.0.0",
|
||||||
"vxe-table": "4.13.7"
|
"vxe-table": "4.17.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify/json": "^2.2.276",
|
"@iconify/json": "^2.2.403",
|
||||||
"@types/crypto-js": "4.2.2",
|
"@types/crypto-js": "4.2.2",
|
||||||
"@types/file-saver": "2.0.7",
|
"@types/file-saver": "2.0.7",
|
||||||
"@types/js-cookie": "3.0.6",
|
"@types/js-cookie": "3.0.6",
|
||||||
"@types/node": "^22.13.4",
|
"@types/node": "^22.19.0",
|
||||||
"@types/nprogress": "0.2.3",
|
"@types/nprogress": "0.2.3",
|
||||||
"@unocss/preset-attributify": "66.5.2",
|
"@unocss/preset-attributify": "66.5.4",
|
||||||
"@unocss/preset-icons": "66.5.2",
|
"@unocss/preset-icons": "66.5.4",
|
||||||
"@unocss/preset-uno": "66.5.2",
|
"@unocss/preset-uno": "66.5.4",
|
||||||
"@vitejs/plugin-vue": "5.2.3",
|
"@vitejs/plugin-vue": "5.2.4",
|
||||||
"@vue/compiler-sfc": "3.5.13",
|
"@vue/compiler-sfc": "3.5.22",
|
||||||
"@vue/eslint-config-prettier": "10.2.0",
|
"@vue/eslint-config-prettier": "10.2.0",
|
||||||
"@vue/eslint-config-typescript": "14.4.0",
|
"@vue/eslint-config-typescript": "14.6.0",
|
||||||
"autoprefixer": "10.4.20",
|
"autoprefixer": "10.4.21",
|
||||||
"eslint": "9.21.0",
|
"eslint": "9.39.1",
|
||||||
"eslint-plugin-prettier": "5.2.3",
|
"eslint-plugin-prettier": "5.5.4",
|
||||||
"eslint-plugin-vue": "9.32.0",
|
"eslint-plugin-vue": "9.33.0",
|
||||||
"globals": "16.0.0",
|
"globals": "16.5.0",
|
||||||
"prettier": "3.5.2",
|
"prettier": "3.6.2",
|
||||||
"sass": "1.87.0",
|
"sass": "1.93.3",
|
||||||
"typescript": "~5.8.3",
|
"typescript": "~5.9.3",
|
||||||
"unocss": "66.5.2",
|
"unocss": "66.5.4",
|
||||||
"unplugin-auto-import": "19.1.2",
|
"unplugin-auto-import": "19.3.0",
|
||||||
"unplugin-icons": "22.1.0",
|
"unplugin-icons": "22.5.0",
|
||||||
"unplugin-vue-components": "28.5.0",
|
"unplugin-vue-components": "28.8.0",
|
||||||
"unplugin-vue-setup-extend-plus": "1.0.1",
|
"unplugin-vue-setup-extend-plus": "1.0.1",
|
||||||
"vite": "6.3.2",
|
"vite": "6.4.1",
|
||||||
"vite-plugin-compression": "0.5.1",
|
"vite-plugin-compression": "0.5.1",
|
||||||
"vite-plugin-svg-icons-ng": "^1.4.0",
|
"vite-plugin-svg-icons-ng": "^1.5.2",
|
||||||
"vite-plugin-vue-devtools": "7.7.5",
|
"vite-plugin-vue-devtools": "8.0.3",
|
||||||
"vitest": "3.1.2",
|
"vitest": "3.2.4",
|
||||||
"vue-tsc": "^2.2.8"
|
"vue-tsc": "^2.2.12"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"quill": "2.0.2"
|
"quill": "2.0.2"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
|
|
||||||
// 绑定账号
|
// 获取跳转URL
|
||||||
export function authBinding(source: string, tenantId: string) {
|
export function authRouterUrl(source: string, tenantId: string) {
|
||||||
return request({
|
return request({
|
||||||
url: '/auth/binding/' + source,
|
url: '/auth/binding/' + source,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<template v-for="(item, index) in options">
|
<template v-for="(item, index) in options">
|
||||||
<template v-if="values.includes(item.value)">
|
<template v-if="isValueMatch(item.value)">
|
||||||
<span
|
<span
|
||||||
v-if="(item.elTagType === 'default' || item.elTagType === '') && (item.elTagClass === '' || item.elTagClass == null)"
|
v-if="(item.elTagType === 'default' || item.elTagType === '') && (item.elTagClass === '' || item.elTagClass == null)"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@@ -50,6 +50,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
|
|
||||||
const values = computed(() => {
|
const values = computed(() => {
|
||||||
if (props.value === '' || props.value === null || typeof props.value === 'undefined') return [];
|
if (props.value === '' || props.value === null || typeof props.value === 'undefined') return [];
|
||||||
|
if (typeof props.value === 'number' || typeof props.value === 'boolean') return [props.value]
|
||||||
return Array.isArray(props.value) ? props.value.map((item) => '' + item) : String(props.value).split(props.separator);
|
return Array.isArray(props.value) ? props.value.map((item) => '' + item) : String(props.value).split(props.separator);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ const unmatch = computed(() => {
|
|||||||
// 传入值为非数组
|
// 传入值为非数组
|
||||||
let unmatch = false; // 添加一个标志来判断是否有未匹配项
|
let unmatch = false; // 添加一个标志来判断是否有未匹配项
|
||||||
values.value.forEach((item) => {
|
values.value.forEach((item) => {
|
||||||
if (!props.options.some((v) => v.value === item)) {
|
if (!props.options.some((v) => v.value == item)) {
|
||||||
unmatch = true; // 如果有未匹配项,将标志设置为true
|
unmatch = true; // 如果有未匹配项,将标志设置为true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -85,6 +86,10 @@ const handleArray = (array: Array<string | number>) => {
|
|||||||
return pre + ' ' + cur;
|
return pre + ' ' + cur;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isValueMatch = (itemValue: any) => {
|
||||||
|
return values.value.some(val => val == itemValue)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<el-checkbox value="3" name="type">短信</el-checkbox>
|
<el-checkbox value="3" name="type">短信</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="附件">
|
<el-form-item label="附件" v-if="buttonObj.file">
|
||||||
<fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
|
<fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="抄送" v-if="buttonObj.copy">
|
<el-form-item label="抄送" v-if="buttonObj.copy">
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ import ElementIcons from '@/plugins/svgicon';
|
|||||||
// permission control
|
// permission control
|
||||||
import './permission';
|
import './permission';
|
||||||
|
|
||||||
|
// 开发者工具保护
|
||||||
|
import { initDevToolsProtection } from '@/utils/devtools-protection';
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
import i18n from '@/lang/index';
|
import i18n from '@/lang/index';
|
||||||
|
|
||||||
@@ -55,3 +58,6 @@ app.use(plugins);
|
|||||||
directive(app);
|
directive(app);
|
||||||
|
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
|
|
||||||
|
// 初始化开发者工具保护(仅生产环境)
|
||||||
|
initDevToolsProtection();
|
||||||
|
|||||||
158
src/utils/devtools-protection.ts
Normal file
158
src/utils/devtools-protection.ts
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* 开发者工具保护
|
||||||
|
* 检测开发者工具是否打开,如果打开则循环执行 debugger 阻止调试
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 检测开发者工具是否打开
|
||||||
|
function detectDevTools(): boolean {
|
||||||
|
try {
|
||||||
|
// 方法1: 检测窗口尺寸差异(最可靠的方法)
|
||||||
|
const widthThreshold = 160; // 开发者工具最小宽度
|
||||||
|
const heightThreshold = 160; // 开发者工具最小高度
|
||||||
|
|
||||||
|
const widthDiff = window.outerWidth - window.innerWidth;
|
||||||
|
const heightDiff = window.outerHeight - window.innerHeight;
|
||||||
|
|
||||||
|
if (widthDiff > widthThreshold || heightDiff > heightThreshold) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法2: 检测 debugger 执行时间(最准确的方法)
|
||||||
|
const start = performance.now();
|
||||||
|
debugger; // 这个 debugger 用于检测,不会被移除
|
||||||
|
const end = performance.now();
|
||||||
|
const timeDiff = end - start;
|
||||||
|
|
||||||
|
// 如果 debugger 被跳过(开发者工具关闭),时间差会很小(通常 < 1ms)
|
||||||
|
// 如果 debugger 暂停(开发者工具打开),时间差会很大(通常 > 100ms)
|
||||||
|
// 降低阈值以提高检测灵敏度
|
||||||
|
if (timeDiff > 10) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法3: 检测控制台对象
|
||||||
|
let devtoolsDetected = false;
|
||||||
|
const element = document.createElement('div');
|
||||||
|
Object.defineProperty(element, 'id', {
|
||||||
|
get: function () {
|
||||||
|
devtoolsDetected = true;
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用 console 来触发 getter(仅在开发者工具打开时)
|
||||||
|
try {
|
||||||
|
console.log(element);
|
||||||
|
console.clear();
|
||||||
|
} catch (e) {
|
||||||
|
// 忽略错误
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devtoolsDetected) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法4: 检测控制台是否被重写(开发者工具打开时)
|
||||||
|
const devtoolsRegex = /./;
|
||||||
|
// @ts-expect-error - 动态添加属性
|
||||||
|
devtoolsRegex.toString = function () {
|
||||||
|
// @ts-expect-error - 动态添加属性
|
||||||
|
this.opened = true;
|
||||||
|
};
|
||||||
|
console.log('%c', devtoolsRegex);
|
||||||
|
// @ts-expect-error - 检查动态添加的属性
|
||||||
|
if (devtoolsRegex.opened) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 如果检测过程中出错,默认返回 false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开发者工具保护主函数
|
||||||
|
export function initDevToolsProtection(): void {
|
||||||
|
// 可以通过环境变量控制是否启用
|
||||||
|
// 生产环境默认启用,开发环境可以通过 VITE_ENABLE_ANTI_DEBUG=true 来启用测试
|
||||||
|
const isProduction = import.meta.env.MODE === 'production';
|
||||||
|
const enableAntiDebug = import.meta.env.VITE_ENABLE_ANTI_DEBUG === 'true' || isProduction;
|
||||||
|
|
||||||
|
if (!enableAntiDebug) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let devToolsOpen = false;
|
||||||
|
let debuggerInterval: number | null = null;
|
||||||
|
|
||||||
|
// 立即执行一次检测
|
||||||
|
const initialCheck = detectDevTools();
|
||||||
|
if (initialCheck) {
|
||||||
|
devToolsOpen = true;
|
||||||
|
debuggerInterval = window.setInterval(() => {
|
||||||
|
debugger; // 循环执行 debugger
|
||||||
|
}, 50); // 更频繁的 debugger,每 50ms 一次
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环检测开发者工具(更频繁的检测)
|
||||||
|
const checkInterval = setInterval(() => {
|
||||||
|
const isOpen = detectDevTools();
|
||||||
|
|
||||||
|
if (isOpen && !devToolsOpen) {
|
||||||
|
// 开发者工具刚打开
|
||||||
|
devToolsOpen = true;
|
||||||
|
|
||||||
|
// 开始循环执行 debugger(更频繁)
|
||||||
|
if (debuggerInterval === null) {
|
||||||
|
debuggerInterval = window.setInterval(() => {
|
||||||
|
debugger; // 循环执行 debugger
|
||||||
|
}, 50); // 每 50ms 执行一次,更激进
|
||||||
|
}
|
||||||
|
} else if (!isOpen && devToolsOpen) {
|
||||||
|
// 开发者工具关闭了
|
||||||
|
devToolsOpen = false;
|
||||||
|
|
||||||
|
// 停止循环 debugger
|
||||||
|
if (debuggerInterval !== null) {
|
||||||
|
clearInterval(debuggerInterval);
|
||||||
|
debuggerInterval = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 500); // 每 500ms 检测一次,更频繁
|
||||||
|
|
||||||
|
// 页面卸载时清理
|
||||||
|
window.addEventListener('beforeunload', () => {
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
if (debuggerInterval !== null) {
|
||||||
|
clearInterval(debuggerInterval);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 额外的检测:监听窗口大小变化
|
||||||
|
let lastWidth = window.innerWidth;
|
||||||
|
let lastHeight = window.innerHeight;
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
const currentWidth = window.innerWidth;
|
||||||
|
const currentHeight = window.innerHeight;
|
||||||
|
|
||||||
|
// 如果窗口尺寸变化很大,可能是开发者工具打开/关闭
|
||||||
|
if (Math.abs(currentWidth - lastWidth) > 200 || Math.abs(currentHeight - lastHeight) > 200) {
|
||||||
|
// 重新检测
|
||||||
|
const isOpen = detectDevTools();
|
||||||
|
if (isOpen && !devToolsOpen) {
|
||||||
|
devToolsOpen = true;
|
||||||
|
if (debuggerInterval === null) {
|
||||||
|
debuggerInterval = window.setInterval(() => {
|
||||||
|
debugger; // 循环执行 debugger
|
||||||
|
}, 50); // 更频繁的 debugger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastWidth = currentWidth;
|
||||||
|
lastHeight = currentHeight;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min.js';
|
import JSEncrypt from 'jsencrypt';
|
||||||
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
||||||
|
|
||||||
const publicKey = import.meta.env.VITE_APP_RSA_PUBLIC_KEY;
|
const publicKey = import.meta.env.VITE_APP_RSA_PUBLIC_KEY;
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ axios.defaults.headers['clientid'] = import.meta.env.VITE_APP_CLIENT_ID;
|
|||||||
// 创建 axios 实例
|
// 创建 axios 实例
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||||
timeout: 50000
|
timeout: 50000,
|
||||||
|
transitional: {
|
||||||
|
// 超时错误更明确
|
||||||
|
clarifyTimeoutError: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 请求拦截器
|
// 请求拦截器
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
* 部署方式 Docker 容器编排 一键部署业务集群<br />
|
* 部署方式 Docker 容器编排 一键部署业务集群<br />
|
||||||
* 国际化 SpringMessage Spring标准国际化方案<br />
|
* 国际化 SpringMessage Spring标准国际化方案<br />
|
||||||
</p>
|
</p>
|
||||||
<p><b>当前版本:</b> <span>v5.5.1</span></p>
|
<p><b>当前版本:</b> <span>v5.5.2</span></p>
|
||||||
<p>
|
<p>
|
||||||
<el-tag type="danger">¥免费开源</el-tag>
|
<el-tag type="danger">¥免费开源</el-tag>
|
||||||
</p>
|
</p>
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
* 分布式监控 Prometheus、Grafana 全方位性能监控<br />
|
* 分布式监控 Prometheus、Grafana 全方位性能监控<br />
|
||||||
* 其余与 Vue 版本一致<br />
|
* 其余与 Vue 版本一致<br />
|
||||||
</p>
|
</p>
|
||||||
<p><b>当前版本:</b> <span>v2.5.1</span></p>
|
<p><b>当前版本:</b> <span>v2.5.2</span></p>
|
||||||
<p>
|
<p>
|
||||||
<el-tag type="danger">¥免费开源</el-tag>
|
<el-tag type="danger">¥免费开源</el-tag>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -73,14 +73,14 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div class="el-login-footer">
|
<div class="el-login-footer">
|
||||||
<span>Copyright © 2018-2025 疯狂的狮子Li All Rights Reserved.</span>
|
<span>Copyright © 2018-2026 疯狂的狮子Li All Rights Reserved.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getCodeImg, getTenantList } from '@/api/login';
|
import { getCodeImg, getTenantList } from '@/api/login';
|
||||||
import { authBinding } from '@/api/system/social/auth';
|
import { authRouterUrl } from '@/api/system/social/auth';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
import { LoginData, TenantVO } from '@/api/types';
|
import { LoginData, TenantVO } from '@/api/types';
|
||||||
import { to } from 'await-to-js';
|
import { to } from 'await-to-js';
|
||||||
@@ -176,6 +176,8 @@ const getCode = async () => {
|
|||||||
const { data } = res;
|
const { data } = res;
|
||||||
captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
|
captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
|
||||||
if (captchaEnabled.value) {
|
if (captchaEnabled.value) {
|
||||||
|
// 刷新验证码时清空输入框
|
||||||
|
loginForm.value.code = '';
|
||||||
codeUrl.value = 'data:image/gif;base64,' + data.img;
|
codeUrl.value = 'data:image/gif;base64,' + data.img;
|
||||||
loginForm.value.uuid = data.uuid;
|
loginForm.value.uuid = data.uuid;
|
||||||
}
|
}
|
||||||
@@ -213,7 +215,7 @@ const initTenantList = async () => {
|
|||||||
* @param type
|
* @param type
|
||||||
*/
|
*/
|
||||||
const doSocialLogin = (type: string) => {
|
const doSocialLogin = (type: string) => {
|
||||||
authBinding(type, loginForm.value.tenantId).then((res: any) => {
|
authRouterUrl(type, loginForm.value.tenantId).then((res: any) => {
|
||||||
if (res.code === HttpStatus.SUCCESS) {
|
if (res.code === HttpStatus.SUCCESS) {
|
||||||
// 获取授权地址跳转
|
// 获取授权地址跳转
|
||||||
window.location.href = res.data;
|
window.location.href = res.data;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div class="el-register-footer">
|
<div class="el-register-footer">
|
||||||
<span>Copyright © 2018-2025 疯狂的狮子Li All Rights Reserved.</span>
|
<span>Copyright © 2018-2026 疯狂的狮子Li All Rights Reserved.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -252,6 +252,21 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col v-if="form.visible !== '0'" :span="12">
|
||||||
|
<el-form-item label="激活路径" prop="form.remark">
|
||||||
|
<template #label>
|
||||||
|
<span>
|
||||||
|
<el-tooltip content="隐藏菜单填写默认激活路由,比如激活父菜单的路由 /system/user" placement="top">
|
||||||
|
<el-icon>
|
||||||
|
<question-filled />
|
||||||
|
</el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
激活路由
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<el-input v-model="form.remark" placeholder="请输入激活路径" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|||||||
Reference in New Issue
Block a user