From d20c490c741ca2cfc7abcb23585da9a43bfc239b Mon Sep 17 00:00:00 2001 From: zhaichao Date: Sun, 23 Aug 2026 15:10:56 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=9C=BA=E5=85=B3=E6=95=99=E5=AD=A6?= =?UTF-8?q?=E6=97=A5=E5=BF=972.=E6=96=B0=E5=A2=9E=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=A8=AA=E5=90=91=E6=8B=96=E6=8B=BD=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=8C=87=E4=BB=A43.=E5=AD=A6=E5=91=98=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/directive/tableDrag/index.js | 96 +++ frontend/src/layout/components/Settings.vue | 219 ++++++ frontend/src/views/classHour/plan/index.vue | 2 +- frontend/src/views/student/score/index.vue | 248 +++++- .../src/views/student/studentInfo/index.vue | 97 ++- .../views/student/warningCondition/index.vue | 541 ++++++++++++- .../src/views/student/warningResult/index.vue | 2 +- .../src/views/subjectMajor/major/index.vue | 716 +++++++++++++++++- .../src/views/teachBusiness/venue/index.vue | 1 + .../src/views/teachingLog/organLog/index.vue | 50 +- frontend/vue.config.js | 2 +- 11 files changed, 1922 insertions(+), 52 deletions(-) create mode 100644 frontend/src/directive/tableDrag/index.js create mode 100644 frontend/src/layout/components/Settings.vue diff --git a/frontend/src/directive/tableDrag/index.js b/frontend/src/directive/tableDrag/index.js new file mode 100644 index 000000000..c48c39631 --- /dev/null +++ b/frontend/src/directive/tableDrag/index.js @@ -0,0 +1,96 @@ +/** + * 表格横向拖拽滚动 + * 隐藏表格的横向滚动条,按住鼠标左键横向拖动即可查看后面的字段。 + * 通过 document 事件委托全局生效,所有 el-table 自动支持,无需逐页绑定。 + * + * 手感优化: + * - 文本选中已在全局样式中禁用(user-select: none),拖拽过程不会再误选文字 + * - 位移以横向为主且超过阈值才触发滚动,轻微手抖、普通点击、纵向拖拽(如行排序)不受影响 + * - 光标仅在真正拖动时变为抓手,平时保持默认 + * - 拖拽结束(确实发生了滚动)后屏蔽本次 click,避免误触发行点击、复选框等 + */ +const DRAG_THRESHOLD = 4 // 横向位移超过该像素且以横向为主,才判定为拖动 + +// 在这些元素上按下鼠标不触发拖拽,保证按钮、复选框等交互不受影响 +const INTERACTIVE_SELECTOR = [ + 'a', 'button', 'input', 'textarea', 'select', 'label', + '.el-button', '.el-checkbox', '.el-radio', '.el-switch', '.el-select', + '.el-link', '.el-dropdown', '.el-tooltip', '.el-color-picker', + '[contenteditable="true"]' +].join(',') + +let wrapper = null +let startX = 0 +let startY = 0 +let startScrollLeft = 0 +let dragging = false + +function isHorizontallyScrollable(el) { + return el.scrollWidth > el.clientWidth + 1 +} + +function handleMouseDown(e) { + if (e.button !== 0) return + if (e.target.closest(INTERACTIVE_SELECTOR)) return + const wrap = e.target.closest('.el-table__body-wrapper') + if (!wrap || !isHorizontallyScrollable(wrap)) return + wrapper = wrap + startX = e.clientX + startY = e.clientY + startScrollLeft = wrap.scrollLeft + dragging = false +} + +function handleMouseMove(e) { + if (!wrapper) return + const dx = e.clientX - startX + const dy = e.clientY - startY + + if (!dragging) { + // 轻微位移视为点击,不触发滚动;位移必须以横向为主,避免与纵向拖拽(如行排序)冲突 + if (Math.abs(dx) <= DRAG_THRESHOLD || Math.abs(dx) <= Math.abs(dy)) return + // 开始拖动:以当前位置为基准,避免起始跳变 + dragging = true + startX = e.clientX + startY = e.clientY + startScrollLeft = wrapper.scrollLeft + wrapper.classList.add('is-dragging') + } + e.preventDefault() + wrapper.scrollLeft = startScrollLeft - (e.clientX - startX) +} + +function handleMouseUp() { + if (!wrapper) return + wrapper.classList.remove('is-dragging') + if (dragging) { + // 拖拽确实发生了滚动,屏蔽本次 click,避免误触发行点击、复选框等 + const blockClick = (ev) => { + ev.preventDefault() + ev.stopPropagation() + document.removeEventListener('click', blockClick, true) + } + document.addEventListener('click', blockClick, true) + } + wrapper = null + dragging = false +} + +// 鼠标拖出窗口外时清理拖拽状态,防止状态残留 +function handleMouseLeave() { + if (!wrapper) return + wrapper.classList.remove('is-dragging') + wrapper = null + dragging = false +} + +const install = function() { + if (install.installed) return + install.installed = true + document.addEventListener('mousedown', handleMouseDown, false) + document.addEventListener('mousemove', handleMouseMove, false) + document.addEventListener('mouseup', handleMouseUp, false) + document.addEventListener('mouseleave', handleMouseLeave, false) +} + +export default install diff --git a/frontend/src/layout/components/Settings.vue b/frontend/src/layout/components/Settings.vue new file mode 100644 index 000000000..67b09e6ca --- /dev/null +++ b/frontend/src/layout/components/Settings.vue @@ -0,0 +1,219 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/views/classHour/plan/index.vue b/frontend/src/views/classHour/plan/index.vue index 0aba39c4a..1b826b751 100644 --- a/frontend/src/views/classHour/plan/index.vue +++ b/frontend/src/views/classHour/plan/index.vue @@ -12,4 +12,4 @@ export default { name: "ClassHourPlan", components: { PlaceholderPage } } - \ No newline at end of file + diff --git a/frontend/src/views/student/score/index.vue b/frontend/src/views/student/score/index.vue index 7eeb355b9..02b862b5a 100644 --- a/frontend/src/views/student/score/index.vue +++ b/frontend/src/views/student/score/index.vue @@ -1,15 +1,249 @@ \ No newline at end of file + + + \ No newline at end of file diff --git a/frontend/src/views/student/studentInfo/index.vue b/frontend/src/views/student/studentInfo/index.vue index f1ddd51d5..83d5c8d88 100644 --- a/frontend/src/views/student/studentInfo/index.vue +++ b/frontend/src/views/student/studentInfo/index.vue @@ -300,12 +300,13 @@ \ No newline at end of file + + + \ No newline at end of file diff --git a/frontend/src/views/student/warningResult/index.vue b/frontend/src/views/student/warningResult/index.vue index 1ae1f8cca..d35e4c500 100644 --- a/frontend/src/views/student/warningResult/index.vue +++ b/frontend/src/views/student/warningResult/index.vue @@ -12,4 +12,4 @@ export default { name: "WarningResult", components: { PlaceholderPage } } - \ No newline at end of file + diff --git a/frontend/src/views/subjectMajor/major/index.vue b/frontend/src/views/subjectMajor/major/index.vue index dfb066aec..89dba7994 100644 --- a/frontend/src/views/subjectMajor/major/index.vue +++ b/frontend/src/views/subjectMajor/major/index.vue @@ -1,15 +1,719 @@ \ No newline at end of file + + + diff --git a/frontend/src/views/teachBusiness/venue/index.vue b/frontend/src/views/teachBusiness/venue/index.vue index f6932722d..f42fb4aaa 100644 --- a/frontend/src/views/teachBusiness/venue/index.vue +++ b/frontend/src/views/teachBusiness/venue/index.vue @@ -10,3 +10,4 @@ export default { components: { PlaceholderPage } } + diff --git a/frontend/src/views/teachingLog/organLog/index.vue b/frontend/src/views/teachingLog/organLog/index.vue index 01cf2fa7c..a5d517e85 100644 --- a/frontend/src/views/teachingLog/organLog/index.vue +++ b/frontend/src/views/teachingLog/organLog/index.vue @@ -1,15 +1,51 @@ \ No newline at end of file + + + \ No newline at end of file diff --git a/frontend/vue.config.js b/frontend/vue.config.js index 32cb96b5a..f3767b08e 100644 --- a/frontend/vue.config.js +++ b/frontend/vue.config.js @@ -9,7 +9,7 @@ const CompressionPlugin = require('compression-webpack-plugin') const name = process.env.VUE_APP_TITLE || '教学管理信息系统' // 网页标题 -const baseUrl = 'http://10.1.1.157:8080' // 后端接口 +const baseUrl = 'http://10.1.1.17:8080' // 后端接口 const port = 80 // 固定开发服务器端口,避免多实例端口混乱