diff --git a/CHANGE.md b/CHANGE.md index 86430e5..85f91fa 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -1,4 +1,28 @@ # 更新日志 +## v0.8.8 (20250118) + +- sz-boot-parent: + - 修改:Jackson序列化添加对`MultipartFile`类型的支持。 + - 修改:`router.whitelist` 属性为Set结构。 + - 优化:系统用户更新时,同步更新缓存信息。 + - 优化:[行为验证码-滑块验证] 增加对double精度的支持。 + - 优化:接口白名单,删除非必要的放行接口。 + - 修复:aop日志打印的一些问题( http-topic.log)。 + - 修复:[代码生成器] 预览时插入按钮SQL问题。 + - 修复:EntityChangeListener 在处理未登录用户数据初始化时的异常问题。 + - 修复:验证码参数`sys.captcha.requestLimit`未启用时redis中仍然记录了次数的问题。 + - 修复:[部门管理] 上级部门为`根部门`时编辑校验未通过的问题。 + - 依赖升级: + - spotless-maven-plugin:2.43.0 -> 2.44.1。 + - mybatis-flex.version:1.10.2 -> 1.10.5。 + - aws.s3.version:2.29.23 -> 2.29.50。 + - springdoc-openapi-starter-webmvc-ui:2.7.0 -> 2.8.3。 + - modelmapper:3.2.1 -> 3.2.2。 + - swagger-annotations:2.2.26 -> 2.2.27。 +- sz-admin: + + - 修复:个别浏览器Socket异常的问题。 + - 优化:[行为验证码-滑块验证] 添加对移动端浏览器的支持。 ## v0.8.7 (20250109) - sz-boot-parent: diff --git a/package.json b/package.json index b18e15b..a648b31 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sz-admin", - "version": "0.8.7", + "version": "0.8.8", "private": true, "scripts": { "dev": "vite", diff --git a/src/components/Captcha/SliderCaptcha.vue b/src/components/Captcha/SliderCaptcha.vue index 388a57b..8fe8787 100644 --- a/src/components/Captcha/SliderCaptcha.vue +++ b/src/components/Captcha/SliderCaptcha.vue @@ -66,6 +66,10 @@ const overlayVisible = ref(false); // 验证结果提示可见性 const isVerifying = ref(false); // 是否正在验证标志 let clearEventListeners: (() => void) | null = null; // 清理事件监听器的函数 const emit = defineEmits(['success']); + +// 检测是否为移动端 +const isMobile = 'ontouchstart' in window || navigator.maxTouchPoints > 0; + // 接收父组件的参数并初始化滑动验证 const acceptParams = () => { fetchSlideData(); @@ -129,37 +133,60 @@ const initializeSlider = () => { let initX = 0; let startTime = 0; - // 鼠标移动事件处理 - const handleMousemove = (e: MouseEvent) => { - offsetX = Math.max(0, Math.min(e.clientX - initX, limit)); + // 移动滑块 + const moveSlider = (clientX: number) => { + offsetX = Math.max(0, Math.min(clientX - initX, limit)); slider.value!.style.left = `${offsetX}px`; imgK.value!.style.left = `${offsetX}px`; trackWidth.value = offsetX; }; - // 鼠标松开事件处理 - const handleMouseup = () => { - document.removeEventListener('mousemove', handleMousemove); - document.removeEventListener('mouseup', handleMouseup); - verifyImageCode({ requestId: slideData.requestId, startTime, moveEncrypted: aesEncrypt(offsetX + '', slideData.secretKey) }); - }; - - // 滑块鼠标按下事件处理 - const handleMousedown = (e: MouseEvent) => { - initX = e.clientX; + // 滑块鼠标和触摸按下事件处理 + const handleStart = (e: MouseEvent | TouchEvent) => { + initX = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX; startTime = Date.now(); - document.addEventListener('mousemove', handleMousemove); - document.addEventListener('mouseup', handleMouseup); + + const handleMove = (e: MouseEvent | TouchEvent) => { + const clientX = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX; + moveSlider(clientX); + }; + + const handleEnd = () => { + document.removeEventListener('mousemove', handleMove); + document.removeEventListener('mouseup', handleEnd); + document.removeEventListener('touchmove', handleMove); + document.removeEventListener('touchend', handleEnd); + verifyImageCode({ + requestId: slideData.requestId, + startTime, + moveEncrypted: aesEncrypt(offsetX + '', slideData.secretKey) + }); + }; + + if (isMobile) { + document.addEventListener('touchmove', handleMove); + document.addEventListener('touchend', handleEnd); + } else { + document.addEventListener('mousemove', handleMove); + document.addEventListener('mouseup', handleEnd); + } }; - // 添加滑块按下事件监听 - slider.value.addEventListener('mousedown', handleMousedown); + // 根据设备类型添加滑块按下事件监听 + if (isMobile) { + slider.value.addEventListener('touchstart', handleStart); + } else { + slider.value.addEventListener('mousedown', handleStart); + } // 清理事件监听器 clearEventListeners = () => { - document.removeEventListener('mousemove', handleMousemove); - document.removeEventListener('mouseup', handleMouseup); - slider.value?.removeEventListener('mousedown', handleMousedown); + document.removeEventListener('mousemove', handleStart); + document.removeEventListener('mouseup', handleStart); + document.removeEventListener('touchmove', handleStart); + document.removeEventListener('touchend', handleStart); + slider.value?.removeEventListener('mousedown', handleStart); + slider.value?.removeEventListener('touchstart', handleStart); }; };