From 51531fa49a75dbaa222dd6c29b82b7a23f1fa251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E6=A2=A6?= Date: Fri, 15 May 2026 16:50:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=90=9C=E7=B4=A2=E6=A0=8F=E6=8A=98?= =?UTF-8?q?=E5=8F=A0=E3=80=81=E4=BC=98=E5=8C=96=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/mj/mj-table/index.scss | 12 ++ .../src/components/mj/mj-table/index.vue | 103 ++++++++++++++++-- .../views/question-bank/paper-mgr/home.vue | 46 ++++---- 3 files changed, 131 insertions(+), 30 deletions(-) diff --git a/playground/src/components/mj/mj-table/index.scss b/playground/src/components/mj/mj-table/index.scss index b6d3ec0..1d20c04 100644 --- a/playground/src/components/mj/mj-table/index.scss +++ b/playground/src/components/mj/mj-table/index.scss @@ -42,6 +42,18 @@ $row_selected_bg: #ebf9ff; // #ffebbc; .vxe-form { background-color: transparent !important; + + .search-form-actions { + display: inline-flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + } + + // 隐藏 vxe 内置折叠触发器(已改用 vxe-button) + .vxe-form--item-trigger-node { + display: none !important; + } } } diff --git a/playground/src/components/mj/mj-table/index.vue b/playground/src/components/mj/mj-table/index.vue index bab5c3b..7b5daa4 100644 --- a/playground/src/components/mj/mj-table/index.vue +++ b/playground/src/components/mj/mj-table/index.vue @@ -102,9 +102,43 @@ const gridRef = ref() const defaultSearchFormOptions = { titleBold: true, data: {}, - collapseNode: true, + collapseStatus: false, } as VxeFormProps +const SEARCH_FORM_ROW_SPAN = 24 + +/** 第二行及以后的筛选项折叠;操作区显示展开/收起 */ +function applySearchFormCollapse(items: any[], defaultSpan = 6) { + let usedSpan = 0 + let rowIndex = 0 + + return items.map((item) => { + if (item.slots?.default === 'action') { + return item + } + if (item.collapseNode) { + return item + } + + const span = Number(item.span ?? defaultSpan) + if (usedSpan + span > SEARCH_FORM_ROW_SPAN) { + rowIndex++ + usedSpan = span + } else { + usedSpan += span + if (usedSpan >= SEARCH_FORM_ROW_SPAN) { + rowIndex++ + usedSpan = 0 + } + } + + if (rowIndex >= 1 && item.folding !== false) { + return { ...item, folding: true } + } + return item + }) +} + // 表格的配置 const checkedProp = 'checked' const defaultGridOptions = { @@ -153,7 +187,11 @@ const gridOptions = ref(defaultGridOptions) // 初始化表格 function initGrid() { - // 表格的列 + const userColumns = (props.grid?.columns || []) as any[] + const leftFixedColumns = userColumns.filter((col) => col.fixed === 'left') + const restColumns = userColumns.filter((col) => col.fixed !== 'left') + + // 表格的列:勾选框 → 左侧固定列(如操作)→ 编辑 → 其余列 const gridColumns = [] if (!_hideCheckbox.value) { gridColumns.push({ @@ -163,6 +201,7 @@ function initGrid() { slots: { header: 'checkbox_header', checkbox: 'checkbox_cell' }, }) } + gridColumns.push(...leftFixedColumns) if (!_hideEdit.value) { gridColumns.push({ title: '编辑', @@ -171,11 +210,13 @@ function initGrid() { slots: { default: 'mj_edit_default' }, }) } + gridColumns.push(...restColumns) // 表格合并 const gridOptionsTmp = { ...defaultGridOptions, data: gridOptions.value.data } + const { columns: _columns, ...gridRest } = props.grid || {} gridOptionsTmp.columns = gridColumns as any - obj.cover(gridOptionsTmp, props.grid) + obj.cover(gridOptionsTmp, gridRest) for (const column of gridOptionsTmp.columns!) { if (column.width || column.minWidth) continue @@ -198,7 +239,7 @@ function initGrid() { ...defaultSearchFormOptions, } obj.cover(searchFormOptions, props.searchForm) - searchFormOptions.items = [ + searchFormOptions.items = applySearchFormCollapse([ { field: 'keyword', title: '关键字', @@ -215,7 +256,7 @@ function initGrid() { { slots: { default: 'action' }, }, - ] + ]) searchFormOptions.data = gridOptions.value.formConfig?.data || {} gridOptionsTmp.formConfig = searchFormOptions } @@ -225,6 +266,7 @@ function initGrid() { } gridOptions.value = gridOptionsTmp + nextTick(() => syncSearchFormCollapsed()) } // 监听配置 @@ -445,6 +487,34 @@ function reload() { gridRef.value.commitProxy('reload') } +const searchFormCollapsed = ref(false) + +const hasSearchFormFold = computed(() => + !!gridOptions.value.formConfig?.items?.some((item: any) => item.folding), +) + +function getSearchFormRef() { + const maps = gridRef.value?.getRefMaps?.() + if (!maps) return null + const formRef = maps.refForm + return formRef?.value ?? formRef +} + +function syncSearchFormCollapsed() { + const formRef = getSearchFormRef() + if (formRef?.getCollapseStatus) { + searchFormCollapsed.value = formRef.getCollapseStatus() + } +} + +function toggleSearchCollapse() { + const formRef = getSearchFormRef() + if (!formRef?.toggleCollapse) return + formRef.toggleCollapse().then(() => { + syncSearchFormCollapsed() + }) +} + // 搜索表单重置 function searchFormReset() { // 清除所有选中 @@ -629,12 +699,23 @@ defineExpose({ diff --git a/playground/src/views/question-bank/paper-mgr/home.vue b/playground/src/views/question-bank/paper-mgr/home.vue index 705da24..dc955ec 100644 --- a/playground/src/views/question-bank/paper-mgr/home.vue +++ b/playground/src/views/question-bank/paper-mgr/home.vue @@ -266,6 +266,15 @@ const searchForm = { // 表格 const grid = { columns: [ + { + title: '操作', + field: 'operation', + width: 300, + fixed: 'left', + slots: { + default: 'operation', + }, + }, { title: '年级', field: 'gradeId', @@ -315,13 +324,6 @@ const grid = { default: 'uploadStatus', }, }, - { - title: '操作', - minWidth: 380, - slots: { - default: 'operation', - }, - }, ], beforeLoadData(params) { if (userInfo.value.isOnlyStaff) { @@ -471,17 +473,22 @@ onMounted(() => { 布置作业 - - 上传试题 - - - 删除试卷 - + + 更多 + + @@ -509,8 +516,9 @@ onMounted(() => { .operation-btns { display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; gap: 4px; + align-items: center; justify-content: flex-start; .el-button + .el-button {